I made a script to unlink selected faces from a shape.
It [u:15wkjmu4]seems[/u:15wkjmu4] that Face.GetPointCount (line 80 in the script) doesn’t always give the same count for faces with colinear points.
See attached image (you can use the last model I sent to test it ; As we discussed earlier, I’ll update the model to change these colinear points… but it’s a good test).
If I select FaceA then FaceB, Face.GetPointCount is returning 3 instead of 5.
If I select FaceB then FaceA, Face.GetPointCount is returning 5 and the script works properly (as shown in the upper right part of the image).
[code:15wkjmu4]’*********************************************************************************
‘ UnlinkFaces
‘
‘ Version for 3DC 8.2.2+
‘
‘ Purpose: Remove selected faces from a shape. The selected faces are put in a new shape
‘
‘ Usage: Select faces from one shape
‘
‘ 2011-06-20 dom107
‘*********************************************************************************
Option Explicit ‘ Requires variable declarations
Sub Main (Scene)
Const CSGSelectFace = 1
Dim GeneralMessage, SceneRootGroup
Dim Message, Shape, NewShape, Group, Face, NewFace
Dim i
Dim MyCount, Material
Dim ActiveObjectsCount
Dim UVList(), PointsList(), NormalsList()
Dim NewUVList(), NewPointsList(), NewNormalsList()
Dim PointIndex, NIndex, UVIndex, FacePntIndex
Dim NewPointIndex, NewNormalIndex, NewUVIndex
Dim nb_uv_list, nb_points_list, nb_normals_list, nb_face_points
Dim InputError
‘ Traces log
Dim MyLog
‘Dim fso
‘Set fso = CreateObject("Scripting.FileSystemObject")
‘Set MyLog = fso.CreateTextFile("d:tempUnlinkFaces.txt", True)
GeneralMessage="Please select any number of faces from one shape."
InputError = FALSE
‘ Count number of selected shapes
ActiveObjectsCount = Scene.GetSelectedShapesCount
‘ Only proceed if faces are selected from one shape
Set Shape = Scene.GetSelectedShape(0)
If ( (ActiveObjectsCount <> 1) OR (Shape.GetSelectionType <> CSGSelectFace) ) Then
MsgBox GeneralMessage
InputError = TRUE
End If
If ( InputError = FALSE ) Then
‘ Create a Group for the shape
Set Group = Scene.CreateGroup
‘ Get the root Group
Set SceneRootGroup = Scene.GetRootGroup
‘ Add it to the scene
SceneRootGroup.AddChild Group
‘ Name the group
Group.SetName "UnlinkFaces Group"
Set NewShape = Scene.CreateShape
MyCount = Shape.GetTextureCoordinateCount
ReDim UVList(MyCount)
ReDim NewUVList(MyCount)
MyCount = Shape.GetPointCount
ReDim PointsList(MyCount)
ReDim NewPointsList(MyCount)
MyCount = Shape.GetNormalCount
ReDim NormalsList(MyCount)
ReDim NewNormalsList(MyCount)
nb_uv_list = 0
nb_points_list = 0
nb_normals_list = 0
For i = 0 To Shape.GetSelectionCount – 1
Set Face = Shape.GetFace(Shape.GetSelectionItem(i))
nb_face_points = Face.GetPointCount
‘ === Copy current face ===
‘MyLog.Writeline(" >>> Original Face " & i & " Face.GetPointCount=" & nb_face_points)
Set NewFace = NewShape.CreateFace
‘ Set the material
NewFace.SetMaterial Face.GetMaterial
For FacePntIndex = 0 to nb_face_points-1
PointIndex = Face.GetPointID(FacePntIndex)
NIndex = Face.GetNormalID(FacePntIndex)
UVIndex = Face.GetTextureCoordinateID(FacePntIndex)
AddUV MyLog, Shape, NewShape, UVIndex, NewUVIndex, UVList, NewUVList, nb_uv_list
AddPoints MyLog, Shape, NewShape, PointIndex, NewPointIndex, PointsList, NewPointsList, nb_points_list
AddNormal MyLog, Shape, NewShape, NIndex, NewNormalIndex, NormalsList, NewNormalsList, nb_normals_list
NewFace.AddPointID NewPointIndex, NewNormalIndex, NewUVIndex
‘MyLog.Writeline(" > Add point to face " & PointIndex & " i=" & i)
Next
‘ === Remove current face ===
Shape.DeleteFace(Shape.GetSelectionItem(i))
Next
‘ Add the new shape to the created Group
Group.AddShape NewShape
‘ Set the new shape name
NewShape.SetName "UnlinkFaces"
End If
End Sub
Sub AddUV(MyLog, Shape, NewShape, UVIndex, NewUVIndex, UVList, NewUVList, nb_uv_list)
Dim i
Dim PointX, PointY
For i = 0 To nb_uv_list-1
If UVIndex = UVList(i) Then
NewUVIndex = NewUVList(i)
Exit sub
End If
Next
Shape.GetTextureCoordinateUV UVIndex, PointX, PointY
‘ Set the new UV
NewUVIndex = NewShape.AddOptimizedTextureCoordinateUV(PointX, PointY)
UVList(nb_uv_list) = UVIndex
NewUVList(nb_uv_list) = NewUVIndex
nb_uv_list = nb_uv_list + 1
‘MyLog.Writeline(" > Store UVid " & UVIndex)
End Sub
Sub AddPoints(MyLog, Shape, NewShape, PointIndex, NewPointIndex, PointsList, NewPointsList, nb_points_list)
Dim i
Dim PointX, PointY, PointZ
Dim X, Y, Z
For i = 0 To nb_points_list-1
If PointIndex = PointsList(i) Then
NewPointIndex = NewPointsList(i)
Exit sub
End If
Next
Shape.GetPointXYZ PointIndex, PointX, PointY, PointZ
‘ Convert to world coordinates
LocalToWorldCoordinates MyLog, Shape.GetParentGroup(), PointX, PointY, PointZ, X, Y, Z, "Offset"
‘ Set the new point
NewPointIndex = NewShape.AddOptimizedPointXYZ(X, Y, Z)
PointsList(nb_points_list) = PointIndex
NewPointsList(nb_points_list) = NewPointIndex
nb_points_list = nb_points_list + 1
‘MyLog.Writeline(" > Store PointId " & PointIndex)
End Sub
Sub AddNormal(MyLog, Shape, NewShape, NIndex, NewNormalIndex, NormalsList, NewNormalsList, nb_normals_list)
Dim i
Dim PointX, PointY, PointZ
For i = 0 To nb_normals_list-1
If NIndex = NormalsList(i) Then
NewNormalIndex = NewNormalsList(i)
Exit sub
End If
Next
Shape.GetNormalXYZ NIndex, PointX, PointY, PointZ
‘ Set the new normal
NewNormalIndex = NewShape.AddOptimizedNormalXYZ(PointX, PointY, PointZ)
NormalsList(nb_normals_list) = NIndex
NewNormalsList(nb_normals_list) = NewNormalIndex
nb_normals_list = nb_normals_list + 1
‘MyLog.Writeline(" > Store NormalId " & NIndex)
End Sub
Sub LocalToWorldCoordinates(MyLog, Group, Xl, Yl, Zl, X, Y, Z, ApplyOffset)
Dim Mat(4, 4)
‘ Get the Transformation Matrix relative to the World
Group.GetTransform Nothing, 0, Mat(0, 0), Mat(0, 1), Mat(0, 2), Mat(0, 3), _
Mat(1, 0), Mat(1, 1), Mat(1, 2), Mat(1, 3), _
Mat(2, 0), Mat(2, 1), Mat(2, 2), Mat(2, 3), _
Mat(3, 0), Mat(3, 1), Mat(3, 2), Mat(3, 3)
‘MyLog.Writeline(" 0 " & Mat(0, 0) & " " & Mat(0, 1) & " " & Mat(0, 2) & " " & Mat(0, 3))
‘MyLog.Writeline(" 1 " & Mat(1, 0) & " " & Mat(1, 1) & " " & Mat(1, 2) & " " & Mat(1, 3))
‘MyLog.Writeline(" 2 " & Mat(2, 0) & " " & Mat(2, 1) & " " & Mat(2, 2) & " " & Mat(2, 3))
‘MyLog.Writeline(" 3 " & Mat(3, 0) & " " & Mat(3, 1) & " " & Mat(3, 2) & " " & Mat(3, 3))
‘ Update with group world orientation
X = Mat(0, 0)*Xl + Mat(0, 1)*Yl + Mat(0, 2)*Zl
Y = Mat(1, 0)*Xl + Mat(1, 1)*Yl + Mat(1, 2)*Zl
Z = Mat(2, 0)*Xl + Mat(2, 1)*Yl + Mat(2, 2)*Zl
If ( ApplyOffset = "Offset" ) Then
‘ Offset to be applied for points not for vectors
X = X + Mat(0, 3)
Y = Y + Mat(1, 3)
Z = Z + Mat(2, 3)
End If
End Sub
[/code:15wkjmu4]