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);
151 case 0:
return "Packed Primitives";
152 case 1:
return "Points";
153 default:
return "Invalid Source";
164 return (i == 0 || i == 1);
175 using namespace HDK_Sample;
177 SOP_CopyPackedVerb::theSOPTypeName,
179 SOP_CopyPacked::myConstructor,
180 SOP_CopyPacked::buildTemplates(
181 "SOP_CopyPacked.C"_sh,
182 SOP_CopyPackedVerb::theDsFile),
188 namespace HDK_Sample {
195 const char *
const SOP_CopyPackedVerb::theDsFile = R
"THEDSFILE(
204 parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Points,)\nkwargs['inputindex'] = 1\nsoputils.selectGroupParm(kwargs)" }
205 parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." }
206 parmtag { "script_action_icon" "BUTTONS_reselect" }
207 parmtag { "sop_input" "1" }
216 template<
typename FUNCTOR>
224 FUNCTOR &&pt_to_prim_functor)
232 [output_geo, packed_prims_input,
233 &bad_prim_group, &bad_prim_group_deleter, &bad_prim_group_lock,
239 for (
GA_Offset dest_primoff = start; dest_primoff <
end; ++dest_primoff, ++i) {
244 GA_Offset source_primoff = pt_to_prim_functor(dest_ptoff);
250 if (primitive_attribs.entries()) {
253 if (vertex_attribs.entries()) {
258 if (!bad_prim_group) {
260 if (!bad_prim_group) {
262 bad_prim_group_deleter = UTmakeUnique<GA_PrimitiveGroup>(*output_geo);
264 bad_prim_group = bad_prim_group_deleter.get();
275 void SOP_CopyPackedVerb::cook(
const CookParms &cookparms)
const
278 auto &&sopparms = cookparms.
parms<SOP_CopyPackedParms>();
291 if (sopparms.getPointGroup().isstring()) {
295 sopparms.getPointGroup().c_str(),
296 points_input,
true, success);
298 if (input_point_group) {
299 output_geo->
mergePoints(*points_input, input_point_group,
true,
false);
311 cookparms.
sopAddError(
SOP_MESSAGE,
"All input primitives for copying must be packed primitives, at the moment.");
315 cookparms.
sopAddError(
SOP_MESSAGE,
"All input packed primitives must be the same primitive type, at the moment.");
327 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
339 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
340 vtx_to_prim->setLink(start_vtxoff+i, start_primoff+i);
354 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
355 vtx_to_pt->setLink(start_vtxoff+i,
GA_Offset(i));
360 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
367 for (
exint i = r.begin(),
n = r.end(); i <
n; ++i) {
377 for (
GA_Offset ptoff = start; ptoff <
end; ++ptoff, ++i) {
378 pt_to_vtx->
setLink(ptoff, start_vtxoff+i);
397 "start_vtxoff and start_primoff should both be zero, since we appended a block to an empty detail.");
410 if (pt_id_attrib.isValid()) {
413 if (!prim_id_attrib.isValid()) {
416 if (!prim_id_attrib.isValid()) {
422 if (prim_id_attrib.isValid()) {
428 for (
GA_Offset primoff = start; primoff <
end; ++primoff) {
435 attriboff = packed_prims_input->
vertexPoint(attriboff);
438 exint id = prim_id_attrib.get(attriboff);
447 id_to_primoff.
insert(
id, primoff);
451 copyPrimitiveData(output_geo, packed_prims_input, bad_prim_group, primitive_attribs, vertex_attribs,
453 const exint id = pt_id_attrib.get(dest_ptoff);
459 auto &&it = id_to_primoff.
find(
id);
460 if (it != id_to_primoff.
end()) {
468 copyPrimitiveData(output_geo, packed_prims_input, bad_prim_group, primitive_attribs, vertex_attribs,
470 const GA_Index source_primind(pt_id_attrib.get(dest_ptoff));
483 if (!prim_name_attrib.isValid()) {
486 if (!prim_name_attrib.isValid()) {
491 if (pt_name_attrib.isValid() && prim_name_attrib.isValid()) {
497 for (
GA_Offset primoff = start; primoff <
end; ++primoff) {
504 attriboff = packed_prims_input->
vertexPoint(attriboff);
519 name_to_primoff.
insert(name, primoff);
523 copyPrimitiveData(output_geo, packed_prims_input, bad_prim_group, primitive_attribs, vertex_attribs,
532 auto &&it = name_to_primoff.
find(name);
533 if (it != name_to_primoff.
end()) {
542 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.");
547 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)
#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)
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.
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
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)