Jump to content

Recommended Posts

This script aligns and orients objects to vertices

 

By:

1)Taking a selection of vertexes and storing them as an array

2)asking the user to pick a piece of geometry

3)calculating the "orientation" of a vertex by

--getting the faces which use that vertex

--calculating and combining their local orientation

4)using that info to create a resultant matrix3 transform

5)copying the target object and applying the matrix3 transform to the object

 

I made it to do things like add studs to fabric, or place oriented objects onto a mesh surface. It could easily be adapted to distribute randomly sized objects over a mesh

 

There is a problem with it - the simple code I wrote, correctly solves the orientation, but it scales up the target object. I used a workaround to solve this by resetting the scale of the object to -1 -1 -1 for x,y,z respectively, on line 27:

 

targetMesh.scale = point3 -1 -1 -1

 

I'm not an expert coder and would like some help making this more elegant. I think I understand the arithmetic I need to do to adjust the matrix at lines 19-21, but I don't know what the relationship is between the original scale of the object and the scale of the transform matrix I'm creating. If I could get some help with this, I'd really appreciate it.

 

---

 

fn orientObjectToVertex targetVertVal targetMesh= (

--work out what bits of the target object have the info we need
targetVert = targetVertVal --getVertSelection $ as array
targetFaces = meshop.getFacesUsingVert $ targetVert as array

--variable points
faceNormal = point3 0 0 0
rightVector = point3 0 0 0
upVector = point3 0 0 0

--constants
faceNum = targetFaces.count
worldUpVector = [0,0,1]
centerPos = getVert $ targetVertVal

for i = 1 to faceNum do (
faceNormal += in coordsys $ (getFaceNormal $ targetFaces[i])
rightVector += normalize (cross worldUpVector faceNormal)
upVector += normalize ( cross rightVector faceNormal)

)

theMatrix = matrix3 rightVector upVector faceNormal centerpos
targetMesh.transform = theMatrix
targetMesh.scale = point3 -1 -1 -1

)



fn g_filter o = superclassof o == Geometryclass
targetMesh = pickObject message:"Pick Target Surface:" filter:g_filter


targetVertArray = getVertSelection $ as array
targetObjectArray = #()

for q = 1 to targetVertArray.count do
(

	targetObjectArray[q] = instance targetMesh
	orientObjectToVertex targetVertArray[q] targetObjectArray[q]

)

Edited by batteryoperatedlettuce
Link to comment
Share on other sites

  • 2 weeks later...

Don't reinvent the wheel - for editable mesh, there's already getNormal function, and matrixFromNormal or arbAxis already do what you want (btw. instead of your worldUpVector variable you should use the built-in z_axis one). So, as an example:

 

(
   local sourceObj = Box()
   local obj = convertToMesh (Sphere())
   obj.selectedVerts = #{2..4}

   if isKindOf obj Editable_Mesh do
       for vert in getVertSelection obj do
           instance sourceObj transform:(translate (arbAxis (getNormal obj vert)) (getVert obj vert))
)

 

The different scale is because you're not making your vectors unit lenght (either by dividing by the number of vectors you added together or by normalizing them. Anyway, there's normal align for single object, placement for multiple, fill for edgeloops, scatter to distribute to verts and advanced painter if you want to go advanced - make it an exercise for yourself if you wish but don't spend much time on it instead of learning these tools.

Link to comment
Share on other sites

  • 10 months later...

I see what you mean. Thanks for your reply. The reason I took a round about way of creating my matrix to get the angle and then reseting the scale is because I want the objects to point outwards from the vertex. By outwards I mean the average angle of all the faces connected to that vertex. If therefore this script were applied to a ball, all the obects would be positioned at the verticies of the ball and face away from the center. For a more complex surface, the object faces "away" from all of the faces connected to the vertex.

 

I haven't tried arbaxis and Z_axis. I usually only write a script when I have something I need to do fairly urgently, which is why it's written using only a few basic commands. I don't actually know how to code "properly". I'm reading into it now and I'm sure I'll be able to write this more efficiently based on the information you've given me.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...