35 #include "SOP_CopyPacked.proto.h"
62 namespace HDK_Sample {
85 virtual void cook(
const CookParms &cookparms)
const;
149 case 0:
return "Packed Primitives";
150 case 1:
return "Points";
151 default:
return "Invalid Source";
162 return (i == 0 || i == 1);
173 using namespace HDK_Sample;
179 "SOP_CopyPacked.C"_sh,
186 namespace HDK_Sample {
202 parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Points,)\nkwargs['inputindex'] = 1\nsoputils.selectGroupParm(kwargs)" }
203 parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." }
204 parmtag { "script_action_icon" "BUTTONS_reselect" }
205 parmtag { "sop_input" "1" }
214 template<
typename FUNCTOR>
222 FUNCTOR &&pt_to_prim_functor)
230 [output_geo, packed_prims_input,
231 &bad_prim_group, &bad_prim_group_deleter, &bad_prim_group_lock,
237 for (
GA_Offset dest_primoff = start; dest_primoff <
end; ++dest_primoff, ++i) {
242 GA_Offset source_primoff = pt_to_prim_functor(dest_ptoff);
248 if (primitive_attribs.entries()) {
251 if (vertex_attribs.entries()) {
256 if (!bad_prim_group) {
258 if (!bad_prim_group) {
260 bad_prim_group_deleter = UTmakeUnique<GA_PrimitiveGroup>(*output_geo);
262 bad_prim_group = bad_prim_group_deleter.get();
276 auto &&sopparms = cookparms.
parms<SOP_CopyPackedParms>();
289 if (sopparms.getPointGroup().isstring()) {
293 sopparms.getPointGroup().c_str(),
294 points_input,
true, success);
296 if (input_point_group) {
297 output_geo->
mergePoints(*points_input, input_point_group,
true,
false);
309 cookparms.
sopAddError(
SOP_MESSAGE,
"All input primitives for copying must be packed primitives, at the moment.");
313 cookparms.
sopAddError(
SOP_MESSAGE,
"All input packed primitives must be the same primitive type, at the moment.");
325 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
337 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
338 vtx_to_prim->setLink(start_vtxoff+i, start_primoff+i);
352 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
353 vtx_to_pt->setLink(start_vtxoff+i,
GA_Offset(i));
358 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
365 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
375 for (
GA_Offset ptoff = start; ptoff <
end; ++ptoff, ++i) {
376 pt_to_vtx->
setLink(ptoff, start_vtxoff+i);
395 "start_vtxoff and start_primoff should both be zero, since we appended a block to an empty detail.");
408 if (pt_id_attrib.isValid()) {
411 if (!prim_id_attrib.isValid()) {
414 if (!prim_id_attrib.isValid()) {
420 if (prim_id_attrib.isValid()) {
426 for (
GA_Offset primoff = start; primoff <
end; ++primoff) {
433 attriboff = packed_prims_input->
vertexPoint(attriboff);
436 exint id = prim_id_attrib.get(attriboff);
445 id_to_primoff.
insert(
id, primoff);
449 copyPrimitiveData(output_geo, packed_prims_input, bad_prim_group, primitive_attribs, vertex_attribs,
451 const exint id = pt_id_attrib.get(dest_ptoff);
457 auto &&it = id_to_primoff.
find(
id);
458 if (it != id_to_primoff.
end()) {
466 copyPrimitiveData(output_geo, packed_prims_input, bad_prim_group, primitive_attribs, vertex_attribs,
468 const GA_Index source_primind(pt_id_attrib.get(dest_ptoff));
481 if (!prim_name_attrib.isValid()) {
484 if (!prim_name_attrib.isValid()) {
489 if (pt_name_attrib.isValid() && prim_name_attrib.isValid()) {
495 for (
GA_Offset primoff = start; primoff <
end; ++primoff) {
502 attriboff = packed_prims_input->
vertexPoint(attriboff);
517 name_to_primoff.
insert(name, primoff);
521 copyPrimitiveData(output_geo, packed_prims_input, bad_prim_group, primitive_attribs, vertex_attribs,
530 auto &&it = name_to_primoff.
find(name);
531 if (it != name_to_primoff.
end()) {
540 cookparms.
sopAddError(
SOP_MESSAGE,
"Either the points must have an id attribute, or both the points and the packed primitives must have a name attribute.");
545 if (bad_prim_group) {
This is the SOP class definition.
A class to manage an ordered array which has fixed offset handles.
SYS_FORCE_INLINE GA_Offset getPrimitiveVertexOffset(GA_Offset primoff, GA_Size i) const
GT_API const UT_StringHolder filename
SYS_FORCE_INLINE GA_Primitive * getPrimitive(GA_Offset prim_off)
void hardenAllPages(GA_Offset start_offset=GA_Offset(0), GA_Offset end_offset=GA_INVALID_OFFSET) override
Harden data pages.
GLuint const GLchar * name
Iteration over a range of elements.
void setChoiceListPtr(const UT_StringRef &name, PRM_ChoiceList *list)
SYS_FORCE_INLINE int getPrimitiveTypeId(GA_Offset primoff) const
SYS_FORCE_INLINE const GA_Attribute * findVertexAttribute(GA_AttributeScope s, const UT_StringRef &name) const
std::pair< iterator, bool > insert(const UT_StringRef &key, const ITEM_T &val)
bool blockAdvance(GA_Offset &start, GA_Offset &end)
bool GAisValid(GA_Size v)
void clearAndDestroy()
Clear all the points/primitives out of this detail.
virtual UT_StringHolder name() const
GLenum GLsizei GLenum GLenum const void * table
UT::ArraySet< std::pair< Key, T >, MULTI, MAX_LOAD_FACTOR_256, Clearer, MapKeyHash< Hash, Key, T >, MapKeyEqual< KeyEqual, Key, T > >::end iterator end()
Returns a non-const end iterator for the set.
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
void newSopOperator(OP_OperatorTable *table)
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
virtual OP_ERROR cookMySop(OP_Context &context) override
Since this SOP implements a verb, cookMySop just delegates to the verb.
static PRM_ChoiceList pointGroupMenu
void assignVertex(GA_Offset vtx, bool update_topology)
Called when loading to set the vertex.
SOP_CopyPacked(OP_Network *net, const char *name, OP_Operator *op)
exint GA_Size
Defines the bit width for index and offset types in GA.
GA_Size deletePrimitives(const GA_Range &range, bool and_points=false)
#define GA_INVALID_OFFSET
iterator find(const Key &key)
GA_Size countPrimitiveType(const GA_PrimitiveTypeId &type) const
UT_ErrorSeverity sopAddError(int code, const char *msg=0, const UT_SourceLocation *loc=0) const
GA_API const UT_StringHolder name
#define UT_ASSERT_MSG(ZZ,...)
SYS_FORCE_INLINE GA_Index primitiveIndex(GA_Offset offset) const
Given a primitive's data offset, return its index.
GA_Range getPointRange(const GA_PointGroup *group=0) const
Get a range of all points in the detail.
const GA_IndexMap & getPointMap() const
Constructs a PRM_Template list from an embedded .ds file or an istream.
virtual ~SOP_CopyPacked()
GA_Offset appendPrimitiveBlock(const GA_PrimitiveTypeId &type, GA_Size nprimitives)
Append a contiguous block of primitives by GA_PrimitiveTypeId.
void UTparallelForLightItems(const Range &range, const Body &body)
PRM_Template * templates() const
std::pair< iterator, bool > insert(const Key &key, const T &val)
static const SOP_NodeVerb::Register< SOP_CopyPackedVerb > theVerb
virtual SOP_NodeParms * allocParms() const
OP_ERROR cookMyselfAsVerb(OP_Context &context)
virtual SOP_NodeCache * allocCache() const
UT_UniquePtr< GA_PrimitiveGroup > GA_PrimitiveGroupUPtr
A handle to simplify manipulation of multiple attributes.
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
static PRM_Template * buildTemplates(const UT_StringHolder &filename, const char *ds_file)
GA_API const UT_StringHolder id
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
SYS_FORCE_INLINE const GA_ATITopology * getPrimitiveRef() const
void setManagesDataIDs(bool onOff)
GA_Topology & getTopology()
SYS_FORCE_INLINE const GA_Attribute * findPrimitiveAttribute(GA_AttributeScope s, const UT_StringRef &name) const
SYS_FORCE_INLINE GA_Index pointIndex(GA_Offset offset) const
Given a point's data offset, return its index.
SYS_FORCE_INLINE bool isTrivialMap() const
void mergePoints(const GEO_Detail &src, const GA_PointGroup *ptGrp=0, bool merge_groups=true, bool keep_internal_groups=true)
const GA_PointGroup * parsePointDetached(const char *pat, const GEO_Detail *pgdp, bool forceexistence, bool &success)
virtual CookMode cookMode(const SOP_NodeParms *parms) const
virtual int isRefInput(unsigned i) const override
virtual const char * inputLabel(unsigned idx) const override
These are the labels that appear when hovering over the inputs.
void replaceWithPoints(const GA_Detail &src, const GA_AttributeFilter *skip=nullptr)
SYS_FORCE_INLINE GA_Offset primitiveOffset(GA_Index index) const
Given a primitive's index (in append order), return its data offset.
virtual void cook(const CookParms &cookparms) const
This is the function that does the actual work.
SYS_FORCE_INLINE const GA_ATITopology * getVertexRef() const
static const UT_StringHolder theSOPTypeName
SYS_FORCE_INLINE GA_Offset offsetFromIndex(GA_Index ordered_index) const
GLdouble GLdouble GLdouble r
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
SYS_FORCE_INLINE GA_Offset getVertexOffset(GA_Size primvertexnum) const
const GU_Detail * inputGeo(exint idx) const
SOP_NodeCache * cache() const
void appendAndCreateAllSource(GA_AttributeOwner destowner, GA_AttributeOwner sourceowner, const char *matchpattern, UT_ArraySet< const GA_Attribute * > *alreadymappeddest=nullptr, bool includegroups=true)
void copyMemberDataFrom(const GEO_PrimPacked &src)
virtual const SOP_NodeVerb * cookVerb() const override
static const char *const theDsFile
This is the parameter interface string, below.
void copyValue(GA_AttributeOwner downer, GA_Offset doffset, GA_AttributeOwner sowner, GA_Offset soffset, Cache *cache=0) const
Automatically expand attribute data pages for threading.
SYS_FORCE_INLINE const GA_Attribute * findPointAttribute(GA_AttributeScope s, const UT_StringRef &name) const
static OP_Node * myConstructor(OP_Network *net, const char *name, OP_Operator *op)
GA_Range getPrimitiveRange(const GA_PrimitiveGroup *group=0) const
Get a range of all primitives in the detail.
void bumpDataIdsForAddOrRemove(bool added_or_removed_points, bool added_or_removed_vertices, bool added_or_removed_primitives)
SYS_FORCE_INLINE GA_Offset pointOffset(GA_Index index) const
Given a point's index (in append order), return its data offset.
SYS_FORCE_INLINE const GA_ATITopology * getPointRef() const
SYS_FORCE_INLINE void addOffset(GA_Offset ai)
GU_DetailHandle & gdh() const
The initial state of gdh depends on the cookMode()
SYS_FORCE_INLINE bool isstring() const
SYS_FORCE_INLINE GA_Offset appendVertexBlock(GA_Size nvertices)
Append new vertices, returning the first offset of the contiguous block.
static bool isPackedPrimitive(const GA_PrimitiveDefinition &pdef)
SYS_FORCE_INLINE GA_Size getNumPoints() const
Return the number of points.
SYS_FORCE_INLINE void setLink(GA_Offset ai, GA_Offset v)