Problem with rotate parameter along with flip

Problem with rotate parameter along with flip

Anonymous
Not applicable
1,906 Views
19 Replies
Message 1 of 20

Problem with rotate parameter along with flip

Anonymous
Not applicable

 

ItemFactoryBase.NewFamilyInstance (Face, XYZ, XYZ, FamilySymbol)

 

 

I've been trying to understand the rotation parameter to this function.  I want to put a 1 object on the face of another object and get it rotated correctly in 1 step.  

 

I have a problem when the object is going along the North / South axis and I'm trying to place it on the East or West face of the object. I get the error "Reference direction is parallel to face normal at insertion point."  I can play around with the reference direction value, but I don't really understand why this is only a problem with the wall going in a certain direction.  

 

Let me know if I need to provide some more information. Thanks!!

0 Likes
1,907 Views
19 Replies
Replies (19)
Message 2 of 20

Anonymous
Not applicable

Hi Lambt,

 

The face normal is a direction that is perpendicular to the face (pointing out from it) the function is looking for a vector which indicates the direction (or orientation) of the family you intend to place.  The function is most likely projecting the vector you give it onto the face and using that to orient the family relative to the face.

 

If you have done something like this (assuming this is a column or something like that and the EW face is the front running east to west) 

ItemFactoryBase.NewFamliyInstance(EWFrontFace, OriginPt, new XYZ(1,0,0), myFamSymb)

that will work great on the "front" face which has a normal of XYZ(0,-1,0) or out of the plane toward you in elevation view.  If you do the same thing for the "right" face or the NS face:

 

ItemFactoryBase.NewFamliyInstance(NSRightFace, OriginPt, new XYZ(1,0,0), myFamSymb)

the normal vector for the right face will be XYZ(1,0,0) and your provided reference direction vector (1,0,0) will then be parallel to it and Revit cannot deduce a rotation from that. 

 

 

What you need to do is to calculate the reference direction relative to the face upon which you want to place it.  If it's always a vertical face that it will be placed on, you could do something as simple as taking the cross product of project Z with the face normal to give you a reference direction to the right as you look at the face.  Of course this won't hold when the face is horizontal so if that's a possibility you may need to handle that case differently. 

 

The bottom line is that you need to provide a reference vector which is not parallel to the face normal in any situation.  Ideally it would also be in the direction which you would like your new family oriented as well. 

Hope that helps,

-Ken

0 Likes
Message 3 of 20

Anonymous
Not applicable

Ken -

 

When I was trying this, I was checking the normal of the Face I was placing the instance on, and I got ( 0, 0, 1 ). So I set my rotation direction as say (0, 1, 0).  This is causing the error to be thrown. This is what is what has confused me, because I am able to get it to place if I set the rotation direction to (0, 0, -1) or (0,0,1) but this seems completely wrong, as this would make a parallel vector to the face normal right?  (Also then the element is off by 90 degrees of what I need it to be)

 

2016-01-11.png

 

This wall is going South to North, and the I'm trying to insert that tile into that frame.  It's odd becuase it works on every angle except NS walls and any wall that is on a 45 degree angle.

 

They will always be placed on a wall, so they should always be a vertical face.  What do you mean "Project Z"? 

 

Pretty new to revit, so I appriciate the help!

 

Thanks

Tyler

 

 

0 Likes
Message 4 of 20

Anonymous
Not applicable
Since the face normal is giving you Project Z (0,0,1) that would suggest that the face you're placing on is either horizontal period or was originally horizontal and has a transform which orients it in the project. Check to see if there is a transform associated with the face.
While this might explain the NS issue, it doesn't seem to explain the 45 degree angle issue (unless I'm missing something obvious... and it wouldn't be the first time)
0 Likes
Message 5 of 20

Anonymous
Not applicable

Ken -

 

If edit the family of the frame, it is 'laying' down, so I guess that would expalin the Z = 1 for the face.  Also looked at the family of the Tile that I am placing and it is the same way, the face I want to place it on is also a Z face.

For the 45 degree, I found the same fix makes it work, putting hte Z to be ( 0, 0, 1 ) for the direction.  The only thing I don't quite understand is why does have the Z for the rotation direction matching the face normal make it work?

 

An Idea I came up with, while not ideal (I'd like to be able get it into position with just the reference direction), I put it in like in the screenshot above, and then I rotate the element afterwards.  If I can't get it all done via the rotation parameter, I'd atleast like to understand how the rotation parameter "rotates" the element when placing.  AKA what values for each direction of X Y and Z actually rotate the element? 

 

Thanks!

 

Tyler

0 Likes
Message 6 of 20

Anonymous
Not applicable
Hi Tyler,
This seems to confirm my suspicion that there is a transform associated with the face. If you're getting this face from the geometryElement, you'll want to see if there is a transform associated with it (and it's not the identity transform).

The idea is that the family geometry is referenced to itself (so to speak) and in the family editor it appears flat and it is. What Revit does when you place it in the project is to simply calculate the transformation of that family geometry (displacement and rotation about multiple axes) which describes the orientation of that geometry in the project. So when you get the normal, you're getting the untransformed normal (up) and not the normal of the face as it exists in the project environment. When you get the geometry you should be able to get the transform associated with the face which you can use to get the actual orientation of the face normal in the project environment.

I'm no expert in curtain wall families but if it's a loadable family used by the system curtain wall family, it most likely has symbol geometry which is referenced with a transform to tell Revit how that geometry is actually oriented in the project. So if you get the normal of the face, it shows the symbol normal and you'd need to transform it to find its actual normal in the project environment. If you'd like something other than digging into transforms, you could use the direction of the curve describing the wall as your reference direction.

you could also try something like this:
http://thebuildingcoder.typepad.com/blog/2011/06/get-transformed-family-instance-geometry.html
0 Likes
Message 7 of 20

Anonymous
Not applicable

Ken -

 

That all seems to make sense, hoping I can get some time to poke at this again later today.  How does the reference direction end up mapping to the "local" geometry of the family?  I'm guessing it somehow tells Revit how to map the local geometry to the project/world geometry?

 

I really appricaite you taking some time to explain all of this, its been EXTREMEL helpful!

 

Thanks

Tyler

0 Likes
Message 8 of 20

Anonymous
Not applicable
Hi Tyler,
No worries, this is fairly complex stuff if you haven't waded through geometry and transforms before. The family 0,0,1 is "likely" being aligned with the specified reference direction (or that ref direction projected onto the face). You could do some experimentation to find out for sure. Ironically, I've done this for a tool but think I just guessed at setting the ref direction and it was right so I didn't look much further to see what direction in the family was being aligned with the ref direction.
Good luck with it, would be nice to see how you go with it all.
0 Likes
Message 9 of 20

Anonymous
Not applicable

When using (0,0,0) it would come in like the image above.  

 

I was finally able to get them to position correctly via the direction parameter, (1, 1, 0) was the magic XYZ.  Now I'm just trying to figure out how this rotates on the face exactly so that it makes some sense 🙂

 

I figured by hand the Face's Normal would be (1, 0, 0) in the project (since its a NS wall, pretty easy 🙂 ), so I'm guessing somehow these works with (1, 1, 0) to direction tile into the frame.  Just trying to figure out how exactly

0 Likes
Message 10 of 20

Anonymous
Not applicable
Oops I meant when I used (0, 0, 1) I'd get the position above.
0 Likes
Message 11 of 20

Anonymous
Not applicable

lambt wrote

I figured by hand the Face's Normal would be (1, 0, 0) in the project (since its a NS wall, pretty easy 🙂 ), so I'm guessing somehow these works with (1, 1, 0) to direction tile into the frame.  Just trying to figure out how exactly


I suspect that it is projecting your specified reference direction onto the face which is why (1,1,0) "works".  This may result in the element being "flipped" for some walls but if your element is symmetric it's probably irrelevant.

 

Here's a nice little video about vector projection:

https://www.khanacademy.org/math/linear-algebra/alternate_bases/orthogonal_projections/v/linear-alg-...

 

0 Likes
Message 12 of 20

Anonymous
Not applicable

Thanks for that video on vector projections.  

 

I had a slight discovery this morning, not sure if this is correct or not but seems to be true for this element atleast.  I still have no idea how it decides to initially place the family, but when I was looking graphing the direction vector and the face normal vector and noticed something, it seems the amount the object is rotated is the same as the angle between the refernce direction and the face normal.  (After seeing your projection video, I think this might have to play a part in why a vector such as (1, 0, 0) does not work, but (1, 1, 0) does).

 

So if I give ref dir of (0, 0, 1) this is the same as the face normal, so it ends up rotation 0 degrees (or not at all):

 

0Rotate.JPG

 

So given reference direction (1, 1, 0), the angle between this and the normal is 90 degrees, so by providing this vector the element is rotated 90 from where it gets placed (in the graphs, red is the face normal).

90Rotate.JPG

 

Now, if I give say (1, 1, 1) as the ref dir, this gives an angle between itself and the face normal of 45 degrees, so the tile seems to rotate 45.

 

45Rotate.JPG

 

And some more playing with the ref dir seemed to continue this, the angle between them was the same the family got rotated.

 

I'm just working on now having the direction of the wall be used to figure the sign of the X and Y's of the reference direction so that it works for all wall directions.

 

Hopefully those pictures help some, seeing it visually helped me alot.  

 

Again just want to say thanks for all you input Ken, its been helpful!

 

Thanks

Tyler 

 

0 Likes
Message 13 of 20

Anonymous
Not applicable
The face normal is only 0,0,1 in the symbol geometry, I think you're still missing the transform which, when applied to the geometry, will result in a face normal which is actually pointing out from the face of the element as it's placed in the project. The actual face normal of the element in the project is *not* 0,0,1. it is a vector directed out from the face. That's why you got an error when you used a refDirection of 1,0,0 for the wall with a face who's normal points to 1,0,0. Even though the face is telling you its normal is 0,0,1, the transformed face normal is actually 1,0,0. You need to get the transformed face normal by getting the transform from the family or the geometry if you want to do apples to apples.
0 Likes
Message 14 of 20

Anonymous
Not applicable
Yeah I forgot about that, but whats odd is on an EW wall this works, since the true normal is (0, 1, 0), so if i send in a ref dir of (1, 0, 0), it'll place.

But on a NS wall, the true normal would be (1, 0, 0). So if I sent in a ref dir of (0, 1, 0) I'd expect it to place, but it gives the "direction is parallel of face normal" error.
0 Likes
Message 15 of 20

Anonymous
Not applicable

Scrap that reply if you saw it.  You have a point.  If the wall is "NS" and we'd expect the normal to be (1,0,0) and you give it (0,1,0) as a ref direction, I would expect it to place properly.

 

See if you can locate the transform and determine what the facenormal actually is "as placed" in the project.

0 Likes
Message 16 of 20

Anonymous
Not applicable

Just saw your edit, so I'll see if I can figure how to get the transform of the geometry to get the normal.

0 Likes
Message 17 of 20

Anonymous
Not applicable

So just to make sure I have this right (the element I am selecting before running this is the square frame family that is already on the wall):

 

var selection = DocManager.Application.ActiveUIDocument.Selection.GetElementIds();
var tileKitId = selection.First().IntegerValue;
var familyInstance = DocManager.Document.GetElement( new ElementId( tileKitId ) ) as FamilyInstance;

// I find the face, and have a variable "face" that represents the PlanarFace
// In this case checking for the faces whose "local" normal is (0, 0, +/-1) Transform transform = familyInstance.GetTransform(); var tNormal = transform.OfVector( face.Normal );

This gives a value of (+/-1, 0, 0) [Depending on if its the E or W face of the object].  Running it on a EW wall I get (0, +/-1, 0).

0 Likes
Message 18 of 20

Anonymous
Not applicable
This looks right though as I mentioned, I'm no expert on curtain wall stuff.
So when you look at the transformed vector:
On wall running EW would expect (0, +/-1, 0);
On wall running NS would expect (+/-1, 0,0);
On 45d wall maybe (0.707, 0.707, 0)?

If so, and on the wall where the transformed normal is 1,0,0 and you're giving a direction of 0,1,0 and it fails: that's inconsistent with my expectations of the placement tool and maybe someone like Jeremy could see where our logic is not correct.
0 Likes
Message 19 of 20

Anonymous
Not applicable
Yeah - on the 45d it was (0.707ish, 0.707ish, 0). It works on the EW wall, but not NS given the project normals of the face.

If I give it (1, 1, 0) when the normal is (+/-1, 0, 0) it does work, So I can just put a case in for just NS walls to tweak the direction, but would like to have the right solution if possible 🙂
0 Likes
Message 20 of 20

Anonymous
Not applicable

Anyone have any idea why this doesn't work? I haven't been able to find out anything new yet?

0 Likes