Get current tap rotation around host part vector

Get current tap rotation around host part vector

Anonymous
Not applicable
2,138 Views
10 Replies
Message 1 of 11

Get current tap rotation around host part vector

Anonymous
Not applicable

Good afternoon, All,

 

When someone has a minute, if they could help me out or point me in the right direction I would appreciate it.

 

First, I am running Revit 2018.2, and I am dealing with Taps connected to straight pieces of duct or pipe.

 

I am disconnecting the taps and saving off connection information to reconnect after some processing, and I am only running into one issue - the current tap rotation around the host duct/pipe.

 

I have found endless articles on how to rotate objects, or get rotation around one of the base axes, but I am not understanding how to tweak these to fit my need.

 

I don't want rotation around any of the base axes, all I want is the current rotation around the vector of the host part centerline.

 

By manually setting the rotation to a value of Pi/2, I have succeeded in making it work for when the duct is facing up, down, left, or right by comparing the host direction to the different view directions, and could probably continue to figure out the values for when the host direction matches ViewDirection or ViewDirection.Negate(), but if the duct or pipe is skewed even a little bit it doesn't work. 

 

In trig there is a way to calculate the angle given an origin, a known point on the circle, and another point that also exists on the circle.

I am trying to apply that formula - but I am not figuring out how to get the proper unit vectors to use.

 

Here is what I have (see code below):

The vector to the tap connector origin from the host centerline

The host centerline vector (I can get the vector on the host that aligns with where the tap vector starts)

 

What I cannot determine (in bold):

The correct unit vectors to use to call unknownVector.AngleOnPlaneTo(unknownRightDirection, hostVector.Direction)

 

The only axis of rotation I am worried about is the host vector itself, not any of the base axes.

 

I am not even moving the tap or the host, I just want to reconnect it, and that requires calling FabricationPart.PlaceAsTap() which calls for two potential rotations (I only need the first one, the other spins the tap in place I believe).

 

Any help would be appreciated.

 

Thanks,

 

Matt

 

Code:

                        var hostCon1Id = 0;
                        var hostCon1 = conManager.Lookup(hostCon1Id);
                        var hostCon2Id = 1;
                        var hostCon2 = conManager.Lookup(hostCon2Id);
                        var hostCenterLine = Line.CreateBound(hostCon1.Origin, hostCon2.Origin);
                        var hostDirection = hostCenterLine.Direction;
                        var tap = connectedPart;
                        var tapCon = connectedConnector;
                        var tapCon1Origin = tapCon.Origin;
                        var tapCon2Id = tapCon.Id == 0 ? 1 : 0;
                        var tapCon2 = tap.ConnectorManager.Lookup(tapCon2Id);
                        var tapCon2Origin = tap.ConnectorManager.Lookup(tapCon2Id).Origin;

                        var a = hostCenterLine.Distance(tapCon.Origin);
                        var c = (hostCon1.Origin - tapCon.Origin).GetLength();
                        var b = Math.Sqrt((Math.Pow(c, 2) - Math.Pow(a, 2)));

                        var distanceToTapCon = Math.Abs(b);

                        var vectorToTapConDir = Line.CreateBound(hostCenterLine.Evaluate(distanceToTapCon, false), tapCon1Origin).Direction;

                        var viewDir = doc.ActiveView.ViewDirection;
                        var viewRightDir = doc.ActiveView.RightDirection;
                        var viewUpDir = doc.ActiveView.UpDirection;

                        var tapRotation1 = 0.0;
                        
                        //(Matt) these work if the host direction lines up with view directions
                        //if (hostDirection.IsAlmostEqualTo(viewUpDir))
                        //    tapRotation1 = viewRightDir.Negate().AngleOnPlaneTo(vectorToTapConDir, viewUpDir);
                        //else if (hostDirection.IsAlmostEqualTo(viewUpDir.Negate()))
                        //    tapRotation1 = viewRightDir.AngleOnPlaneTo(vectorToTapConDir, viewUpDir.Negate());
                        //else if (hostDirection.IsAlmostEqualTo(viewRightDir))
                        //    tapRotation1 = viewUpDir.AngleOnPlaneTo(vectorToTapConDir, viewRightDir);
                        //else if (hostDirection.IsAlmostEqualTo(viewRightDir.Negate()))
                        // 
0 Likes
Accepted solutions (2)
2,139 Views
10 Replies
Replies (10)
Message 2 of 11

jeremytammik
Autodesk
Autodesk

Can't you just use the original connector's transform?

 

It provides origin, X, Y and Z axes.

 

I see you are using `tapCon.Origin`, but I do not see any use of the three axes.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 3 of 11

Anonymous
Not applicable
Hi, Jeremy, thanks for replying!

I woud try the transform, but maybe I don't fully understand transforms.

I can get it, that's not a problem, but that contains information about
that tap's rotation around the x, y, and z axes - doesn't it?

Instead, I'm wanting the rotation around a given vector, in this case the
host vector, regardless of the host's orientation to x, y, z.

Can I get that from transform? Maybe i don't really understand them enough,
but transforms can contain up to three axes of rotation and I'm not
interested in any "axis" except the host centerline.

I'm basically wanting to pretend I'm looking straight through the inside of
the duct or pipe, pretend there is a unit circle with its origin on the
host centerline lined up with the tap vector, with the tap connector origin
on the edge of the circle.

Then I would need to get the "down" direction of the host and measure the
angle counterclockwise from there to the tap vector and that should be my
correct rotation.

Simplest case:
We have a piece of duct with centerpoint at origin, centerline going from
(0,-2,0) to (0,2,0), and a tap on every side. Let's assume host direction
matches View.UpDirection.

Tap rotation would be:
View.UpDirection.Negate ().AngleOnPlaneTo (tapDir, View.RightDirection)

To do it regardless of host orientation, I guess the two vectors I would
need are host "down" direction, and host right direction, and then this
should always work:
hostDownDir.AngleOnPlaneTo (tapDir, hostRightDir).

Unless I am totally off base.

And even if this gives me a rotation that pops the tap to the wrong side,
as long as it is consistently the same wrong side regardless of host
orientation then a little tweaking will get me the right one. For instance,
maybe it's not the down and right direction I need, maybe it's host right
and up, or something like that.

Thanks again,

Matt
0 Likes
Message 4 of 11

Anonymous
Not applicable
Whoops,

In the simple case, the correct rotation would be:
ViewDir.Negate().AngleOnPlaneTo(tapDir, viewRightDir)

I'm looking for (i believe):
HostDownDir.AngleOnPlaneTo(tapDir, hostRightDir)

I think. I've been looking at this so long I'm starting to confuse myself.

I might have figured out a way to determine it without using angleOnPlaneTo(), but I would really like to do this the proper way.

Thanks again,
Matt
0 Likes
Message 5 of 11

jeremytammik
Autodesk
Autodesk
Accepted solution

Dear Matt, 

 

You say:

 

>  I would try the transform...  but that contains information about that tap's rotation around the x, y, and z axes - doesn't it?

 

Nope.

 

The connector's X, Y and Z axes are unit vectors.

 

  • Z points straight 'out' looking out from the connector surface.
  • X points 'right' looking out from the connector surface.
  • Y points 'up' looking out from the connector surface.

 

http://thebuildingcoder.typepad.com/blog/2012/05/connector-orientation.html

 

Therefore, you can use them in conjunction with the pipe location line to determine the vector you are after.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 6 of 11

Anonymous
Not applicable

@jeremytammik

 

Alright, perfect! 

 

That's the piece of information I was missing. Thank you so much for clarifying!

 

 

I thought transform was was the axes of the whole project - and I was always searching for rotation to tap not connector orientation, so I'm certain the link you referenced will get me where I need to go.

 

I found out part of my problem was I was never actually disconnecting the tap from the other pieces connected to it, just saving off the information. So it was getting disconnected from the host, but when I went to place it back Revit balked and I thought it was because I supplied the wrong rotation (which I am if the host is skewed, anyway).

 

I'll give it a shot and let you know, thanks again,

 

Matt

 

0 Likes
Message 7 of 11

Anonymous
Not applicable
Accepted solution

@jeremytammik

 

Success!!!

 

Almost completely there, it turns out i do actually need to worry about the spin of the tap, too, but from what I've got so far that should not be hard to figure out.

 

This is the correct way to go (except for spin):

 

                        
var hostDir = hostCon1.CoordinateSystem.BasisZ.Negate(); //Or hostCon2.CoordinateSystem.BasisZ
var hostDownDir = hostCon2.CoordinateSystem.BasisY.Negate(); var hostRightDir = hostCon2.CoordinateSystem.BasisX; var tapDir = tapCon.CoordinateSystem.BasisZ; var tapRotation1 = hostRightDir.Negate().AngleOnPlaneTo(tapDir, hostDir);

 

Huzzah! I've been struggling with this for over a week.

 

Finally 🙂

 

What a relief, thank you so much!

 

Matt

 

 

0 Likes
Message 8 of 11

jeremytammik
Autodesk
Autodesk

Congratulations on nailing it!

 

Sorry it took us so long to pinpoint the issue.

 

I am glad that all the information required is actually available somewhere.

 

I love geometry and vectors and transforms and stuff, though, I'm happy/ashamed/sorry/proud to admin  🙂

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 9 of 11

jeremytammik
Autodesk
Autodesk

Dear Matt,

 

If you would like to share the final code including spin handling once that is in place, I think this might make a nice blog post.

 

What do you think?

 

If you agree, would you like to share a screen shot or two explaining what you originally had and needed, the steps we walked through, and what the final result looks like?

 

Thank you!

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 10 of 11

Anonymous
Not applicable
I can, yes, though I'll have to remove any code indicating the reason why
it was needed 🙂 that part I'm not allowed to share, but yeah that won't be
a problem.

I love math, always have, it's just trig I'm the weakest on (calculus was
my favorite). Our teacher that year got tongue cancer the second week in
and we had a sub the rest of the year 😕

Anyway, I'll let you know when I get it ready.

Thanks again,

Matt
0 Likes
Message 11 of 11

shibuchellappan
Participant
Participant

Excellent, i have just one question. if you can help me please. Can we insert a tap other than rolling offset method(doc.create.NewTakeoffFitting(PipeConnector,PipeCure). Can we insert a tap like insert fitting using doc.Create.NewFamilyInstance(...). if YES please let meknow

Thanks

Shibu

 

0 Likes