Finding interior points with valence two


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 )