35 #include "SOP_CopyPacked.proto.h"
62 using namespace UT::Literal;
64 namespace HDK_Sample {
87 virtual void cook(
const CookParms &cookparms)
const;
103 const UT_StringHolder SOP_CopyPackedVerb::theSOPTypeName(
"hdk_copypacked"_sh);
127 return SOP_CopyPackedVerb::theVerb.get();
135 mySopFlags.setManagesDataIDs(
true);
143 return cookMyselfAsVerb(context);
152 case 0:
return "Packed Primitives";
153 case 1:
return "Points";
154 default:
return "Invalid Source";
166 return (i == 0 || i == 1);
177 using namespace HDK_Sample;
179 SOP_CopyPackedVerb::theSOPTypeName,
181 SOP_CopyPacked::myConstructor,
182 SOP_CopyPacked::buildTemplates(
183 "SOP_CopyPacked.C"_sh,
184 SOP_CopyPackedVerb::theDsFile),
190 namespace HDK_Sample {
197 const char *
const SOP_CopyPackedVerb::theDsFile = R
"THEDSFILE(
206 parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Points,)\nkwargs['inputindex'] = 1\nsoputils.selectGroupParm(kwargs)" }
207 parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." }
208 parmtag { "script_action_icon" "BUTTONS_reselect" }
209 parmtag { "sop_input" "1" }
218 template<
typename FUNCTOR>
226 FUNCTOR &&pt_to_prim_functor)
234 [output_geo, packed_prims_input,
235 &bad_prim_group, &bad_prim_group_deleter, &bad_prim_group_lock,
241 for (
GA_Offset dest_primoff = start; dest_primoff <
end; ++dest_primoff, ++i) {
246 GA_Offset source_primoff = pt_to_prim_functor(dest_ptoff);
252 if (primitive_attribs.entries()) {
255 if (vertex_attribs.entries()) {
260 if (!bad_prim_group) {
262 if (!bad_prim_group) {
264 bad_prim_group_deleter = UTmakeUnique<GA_PrimitiveGroup>(*output_geo);
266 bad_prim_group = bad_prim_group_deleter.get();
277 void SOP_CopyPackedVerb::cook(
const CookParms &cookparms)
const
280 auto &&sopparms = cookparms.
parms<SOP_CopyPackedParms>();
293 if (sopparms.getPointGroup().isstring()) {
297 sopparms.getPointGroup().c_str(),
298 points_input,
true, success);
300 if (input_point_group) {
301 output_geo->
mergePoints(*points_input, input_point_group,
true,
false);
313 cookparms.
sopAddError(
SOP_MESSAGE,
"All input primitives for copying must be packed primitives, at the moment.");
317 cookparms.
sopAddError(
SOP_MESSAGE,
"All input packed primitives must be the same primitive type, at the moment.");
329 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
341 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
342 vtx_to_prim->setLink(start_vtxoff+i, start_primoff+i);
356 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
357 vtx_to_pt->setLink(start_vtxoff+i,
GA_Offset(i));
362 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
369 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
379 for (
GA_Offset ptoff = start; ptoff <
end; ++ptoff, ++i) {
380 pt_to_vtx->
setLink(ptoff, start_vtxoff+i);
399 "start_vtxoff and start_primoff should both be zero, since we appended a block to an empty detail.");
412 if (pt_id_attrib.isValid()) {
415 if (!prim_id_attrib.isValid()) {
418 if (!prim_id_attrib.isValid()) {
424 if (prim_id_attrib.isValid()) {
430 for (
GA_Offset primoff = start; primoff <
end; ++primoff) {
437 attriboff = packed_prims_input->
vertexPoint(attriboff);
440 exint id = prim_id_attrib.get(attriboff);
449 id_to_primoff.
insert(
id, primoff);
453 copyPrimitiveData(output_geo, packed_prims_input, bad_prim_group, primitive_attribs, vertex_attribs,
455 const exint id = pt_id_attrib.get(dest_ptoff);
461 auto &&it = id_to_primoff.
find(
id);
462 if (it != id_to_primoff.
end()) {
470 copyPrimitiveData(output_geo, packed_prims_input, bad_prim_group, primitive_attribs, vertex_attribs,
472 const GA_Index source_primind(pt_id_attrib.get(dest_ptoff));
485 if (!prim_name_attrib.isValid()) {
488 if (!prim_name_attrib.isValid()) {
493 if (pt_name_attrib.isValid() && prim_name_attrib.isValid()) {
499 for (
GA_Offset primoff = start; primoff <
end; ++primoff) {
506 attriboff = packed_prims_input->
vertexPoint(attriboff);
521 name_to_primoff.
insert(name, primoff);
525 copyPrimitiveData(output_geo, packed_prims_input, bad_prim_group, primitive_attribs, vertex_attribs,
534 auto &&it = name_to_primoff.
find(name);
535 if (it != name_to_primoff.
end()) {
544 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.");
549 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.
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)
void clearAndDestroy()
Clear all the points/primitives out of this detail.
virtual UT_StringHolder name() const
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.
void UTparallelForLightItems(const Range &range, const Body &body, const bool force_use_task_scope=true)
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)
SYS_FORCE_INLINE bool GAisValid(GA_Size v)
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)
virtual const char * inputLabel(OP_InputIdx idx) const override
These are the labels that appear when hovering over the inputs.
#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.
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
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.
GLuint const GLchar * name
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
GLenum GLenum GLsizei void * table
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)
GA_API const UT_StringHolder parms
virtual CookMode cookMode(const SOP_NodeParms *parms) const
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.
SYS_FORCE_INLINE const GA_ATITopology * getVertexRef() const
static const UT_StringHolder theSOPTypeName
SYS_FORCE_INLINE GA_Offset offsetFromIndex(GA_Index ordered_index) const
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
virtual int isRefInput(OP_InputIdx i) const override
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)