How you grab the points is very important as it dictates the type of
information returned, and options for converting to/from other subcomponent
types. Also, Softimage differentiates between the generic subcomponent
classes vs. geometry-specific subcomponent classes. You need to pay
attention to these details to write successful efficient code.
When you access points using Object.ActivePrimitive.Geometry.Points, you are
accessing the generic "Point" class which is intended to abstract details
away so you can deal with any type of geometry that has points (polygon
mesh, NURBS Curve, NURBS Surface, ...) in your code without having to fork
it for each case. The downside is the Point class only has trivial
information about the points common to all the supported geometry types.
You won't get too much beyond the point's position, id, and a few other
simple details. When you query the class's type, it will return "Point".
The other generic subcomponent classes are 'Samples', 'Segments', and
'Facets'.
When you access points using Object.ActivePrimitive.Geometry.Vertices (in
the case of a polygon mesh), you are accessing the geometry-specific
"Vertex" class. You gain deep access to whatever is available for vertices
on a polygon mesh including polygon nodes, edges, and so on, and you also
gain methods to give your code more options to do it's job. The downside is
it is not compatible with other types of geometries such as NURBS Curves,
NURBS Surfaces, and so on. You should use geometry-specific classes any
time you are working with geometries at more than a trivial level (such as
modeling operations).
So the tradeoff is knowing when your code will deal with geometry
specifically vs. generically. Other than selection filters or other general
tools, you won't use the generic subcomponent classes very often. If you're
writing a tool which deforms an object by manipulating point positions, you
can probably get away with using the generic point class so you can support
all geometry types with one simple set of coded instructions. However, if
you only plan to support one type of geometry or need deeper access to the
guts of the object, then you'll likely have to use the geometry-specific
classes.
When you access subcomponents through the selection list, the subcomponents
are packaged together and tucked into a 'CollectionItem' object. That is,
if there are 3 selected objects in the scene and each object has selected
subcomponents, then the Selection list will contain only 3 indices, each
with a CollectionItem object representing the selected subcomponents of each
object - no matter how many individual subcomponents are selected. So
querying the selection list for subcomponents will return a CollectionItem
object containing the selected subcomponents for each selected object in the
scene.
To gain access to the individual subcomponents, you must convert the
CollectionItem to a collection of SubComponents using
CollectionItem.SubComponent methods. For example, if points are selected,
then to get access to the individual points you use:
// Get selection from the selection list
// returns a CollectionItem with all subcomponents grouped together in a
single package.
var oItem = Selection(0);
// get the object owning the subcomponents.
// (useful downstream when you need to know what methods you'll have
available.)
var oObject = oItem.SubComponent.Parent3DObject;
// convert to a collection of subcomponent objects so they can be accessed
individually.
// This will be much faster than iterating through a loop using
Geometry.CreateSubComponent()
var oSubComponents = oItem.SubComponent.ComponentCollection;
// verify
for ( var i = 0; i < oSubComponents .Count; i++ ) {
var oSubComponents = oSubComponents(i);
LogMessage( "SubComponent[type, class, id]: " + oSubComponents .Type +
", " + ClassName( oSubComponents ) + ", " + oSubComponents .Index,
siComment );
}
// by checking the object type, we learn what methods or classes we have
available:
if ( oObject.Type == "polymsh" ) {
// polygon mesh - polygon nodes, vertices, edges, polygons
var oVertices = oObject.ActivePrimitive.Geometry.Vertices;
var oEdges = oObject.ActivePrimitive.Geometry.Edges;
var oPolygons = oObject.ActivePrimitive.Geometry.Polygons;
var oPolygonNodes = oObject.ActivePrimitive.Geometry.Nodes;
} else if ( oObject.Type == "surfmsh" ) {
// NURBS Surface mesh - samples, control points, knots, isocurves,
subsurfaces
var NbSurfaces = oObject.ActivePrimitive.Geometry.Surfaces.Count;
var oSubSurfaces = oObject.ActivePrimitive.Geometry.Surfaces;
var oControlPoints = oSubSurfaces(0).ControlPoints;
} else if ( oObject.Type == "crvlist" ) {
// NURBS Curve - control points, knots, subcurves
var oSubCurves = oObject.ActivePrimitive.Geometry.Curves;
var oControlPoints = oSubCurves(0).ControlPoints;
}
// However, if we don't care about geometry type, we can get
// some of the same info generically (albeit, with less details):
var oPoints = oObject.ActivePrimitive.Geometry.Points;
var oSegments = oObject.ActivePrimitive.Geometry.Segments;
var oFacets = oObject.ActivePrimitive.Geometry.Facets;
var oSamples = oObject.ActivePrimitive.Geometry.Samples;
Now, to address how to convert between points and edges/polygons, you simply
have to navigate the point/vertex class you're accessing to do that. I
suggest using the vertex class instead of the generic point class (in the
case of a polygon mesh). You'll have better access to the neighbor methods
if you want convenience. However, you also have direct methods for faster
access.
for example:
// assume object with selected edges
var oItem = Selection(0);
// convert CollectionItem to collection of edge subcomponents
var oEdges = oItem.SubComponent.ComponentCollection;
var oSelectedVertices = XSIFactory.CreateActiveXObject( "XSI.Collection" );
oSelectedVertices.Clear();
oSelectedVertices.Unique = true;
// for each edge, get the vertices which make up the edge
for ( var i = 0; i < oEdges.Count; i++ ) {
var oEdge = oEdges(i);
// Again, we have a choice of generic vs. geometry-specific.
// choose according to your needs, but remember crossing over is
// difficult and not always available. So don't paint yourself into a
corner.
// Downstream code usually determines the choice.
// suggestion: do not mix n' match between generic/specific in same
code.
var oEdgeVertices = oEdge.Vertices; // (geometry-specific)
var oEdgePoints = oEdge.Points; // (generic)
oSelectedVertices.AddItems( oEdgeVertices(0), oEdgeVertices(1) );
}
// verify
if ( oSelectedVertices.Count > 0 ) {
LogMessage( "Selected vertices[" + oSelectedVertices.Count + "]: " +
oSelectedVertices.GetAsText(), siComment );
} else {
LogMessage( "No vertices selected", siComment );
}
Matt
-----Original Message-----
From: [email protected]
Sent: Saturday, April 02, 2016 12:00 PM
To: [email protected]
Subject: Softimage Digest, Vol 89, Issue 5
Send Softimage mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://listproc.autodesk.com/mailman/listinfo/softimage
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Softimage digest..."
Today's Topics:
1. Re: convert edge/poly collections to points (Martin Yara)
----------------------------------------------------------------------
Message: 1
Date: Sun, 3 Apr 2016 01:22:14 +0900
From: Martin Yara <[email protected]>
Subject: Re: convert edge/poly collections to points
To: "[email protected]"
<[email protected]>
Message-ID:
<caexmsfgy7ydjbuvpzov6foikamst3oqq4ximhq_owpn5xu5...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Taking a look at my old scripts I've just remembered how I used to do it.
oColl = obj.ActivePrimitive.Geometry.CreateSubComponent(c.siVertexCluster)
loop through the NeighborVertices and
oColl.AddElement( point.index)
I'm not sure if that's the best way to do it but it works. If it isn't, I'd
appreciate any suggestion.
Thanks
On Sat, Apr 2, 2016 at 10:13 PM, Martin Yara <[email protected]> wrote:
> Hi, I wrote a code that is using point collection from the selection or
> the object points:
>
> obj.ActivePrimitive.Geometry.Points
> or
> Selection(0).SubComponent.ComponentCollection
>
> Now I want to make it compatible with edge or poly selections, so I'm
> trying to get the neighbor vertices from them, but if I gather
> the NeighborVertices in a new colletion I get a different type of
> collection.
>
> I don't know the technical part of this but a LogMessage (point) in the
> first case give me 'Vertex', while in the gathered collection give me :
> 'Biped_Nulls.Man.pnt[1044]'.
>
> I'd like to have a collection like the first one so I don't have to change
> my whole code based on vertices. Is it possible?
>
> Thanks
>
> Martin
------
Softimage Mailing List.
To unsubscribe, send a mail to [email protected] with
"unsubscribe" in the subject, and reply to confirm.