A point with “valence 2” is a point with two incident (neighbour) edges. You could write a script to find these points, but it’s even easier to do with ICE:
Notice that some of the tagged points look like they have more than 2 neighbour edges. What’s happening there is that there are several vertices on top of each other:
Here’s a Python script that builds the ICE tree and then uses it to select all the interior points with valence 2.
hat tip: Fabricio Chamon
I also did this as a custom filter, maybe I’ll post that later.
from siutils import si from siutils import log # LogMessage from siutils import disp # win32com.client.Dispatch from siutils import C # win32com.client.constants # # Build the ICE tree that finds the interior points with valence two # def BuildICETree( oObject ): oIceTree = si.ApplyOp("ICETree", oObject.FullName, C.siNode, "", "", 0)(0) oIceTree.Name = "PS_ValenceTwoFilter" oAnd = si.AddICENode("$XSI_DSPRESETS\\ICENodes\\CombineLogicNode.Preset", oIceTree ) # # Get self.VertexIsCorner -> Not -> And # oNot = si.AddICENode("$XSI_DSPRESETS\\ICENodes\\NotNode.Preset", oIceTree ) oGetVertexIsCorner = si.AddICENode("$XSI_DSPRESETS\\ICENodes\\GetDataNode.Preset", oIceTree ) oGetVertexIsCorner.Parameters( "Reference" ).Value = "self.VertexIsCorner" si.ConnectICENodes( oNot.InputPorts("Value"), oGetVertexIsCorner.OutputPorts( "value" ) ) si.ConnectICENodes( oAnd.InputPorts( "Value1" ), oNot.OutputPorts("result") ); # # Get self.VertexToEdges -> Get Array Size -> = -> And # oGetVertexToEdges = si.AddICENode("$XSI_DSPRESETS\\ICENodes\\GetDataNode.Preset", oIceTree ) oGetVertexToEdges.Parameters( "Reference" ).Value = "self.VertexToEdges" oArraySize = si.AddICENode("$XSI_DSPRESETS\\ICENodes\\GetArraySizeNode.Preset", oIceTree ) oCompare = si.AddICENode("$XSI_DSPRESETS\\ICENodes\\CompareNode.Preset", oIceTree ) si.ConnectICENodes( oArraySize.InputPorts("Array"), oGetVertexToEdges.OutputPorts("value") ) si.ConnectICENodes( oCompare.InputPorts("first"), oArraySize.OutputPorts("size") ) oCompare.InputPorts("second").Value = 2 si.AddPortToICENode( oAnd.InputPorts("Value1"), "siNodePortDataInsertionLocationAfter") si.ConnectICENodes( oAnd.InputPorts("Value2"), oCompare.OutputPorts("result") ) # # Set Data -> ICETree # oSetData = si.AddICECompoundNode("Set Data", oIceTree ) si.SetValue( oSetData.FullName + ".Reference", "self._PsValenceTwoFlag", "") si.ConnectICENodes( oSetData.InputPorts("Value"), oAnd.OutputPorts( "result" ) ) si.ConnectICENodes( oIceTree.InputPorts("port1"), oSetData.OutputPorts("Execute") ) si.DisplayPortValues(oSetData.InputPorts( "Value" ), True, 0, True, "", 0, 0, 0, 1, False, True, 1, 0.5, 0, 1, False, 0, 10000, 1, False, False, 0, 10, False, True, False, 100) return oIceTree # # Select all points with the ICE attribute _PsValenceTwoFlag=True # def SelectInteriorPoints_with_ValenceTwo( oObject ): a = oObject.ActivePrimitive.ICEAttributes("_PsValenceTwoFlag") if a is not None: d = a.DataArray if len(d) > 0 and a.IsConstant == False: Application.SelectGeometryComponents( "%s.pnt[%s]" %( oObject.FullName, ",".join(["%s" %(ix) for ix in range(len(d)) if d[ix] == -1]) ) ) #-------------------------------------------------------------- # Select interior points with valence 2 #-------------------------------------------------------------- if si.Selection.Count > 0 and si.ClassName( si.Selection(0) ) != "CollectionItem" : oObject = si.Selection(0); else: oObject = si.PickObject( "Pick object" )(2) if oObject != None and oObject.IsClassOf( C.siX3DObjectID ): tree = BuildICETree( oObject ) SelectInteriorPoints_with_ValenceTwo( oObject ) si.DeleteObj( tree )
Excellent Script. I’ve wished for something like this for Softimage for a while. Filter non-manifold geometry would also be helpful script, if possible.
Thank You.