Announcements

Starting in December, we will archive content from the community that is 10 years and older. This FAQ provides more information.

Reveals at Ends of Walls

msweeneyPES
Participant
Participant

Reveals at Ends of Walls

msweeneyPES
Participant
Participant

I am working on writing out a macro to create a reveal at each end of a wall, so placing two vertical reveals on a wall, one at the start and one at the end. I've got the concept working on walls that are created individually. Where it seems to have an issue is when i try to use it and there are walls that have been split using the "Split Element" tool in revit. When it encounters those walls it just errors out saying that "Could not create Reveal. Sweep position is outside of its wall. Please check sweep parameters." - 

 

In the image below the wall was one wall and I used split element, then ran the script. Also included is a bit of the code for the placement - it is largely hardcoded and prototypish at the moment but I'm trying to make sure the concept works. 

 

The behavior of the walls that have been more or less "created" from the split element tool is really confusing me. Has anyone run across this and can shed some light? 

 

Thanks

revealplace.PNG  

			Element wsType;
			wsType = wsTypeColl.FirstElement();
			
			var wsStart = new WallSweepInfo(WallSweepType.Reveal, true);
        	var wsEnd = new WallSweepInfo(WallSweepType.Reveal, true);
        				      	
			Transaction curTrans = new Transaction(curDoc, "Create Reveals");
			curTrans.Start();
			
			foreach(Wall tw in tiltWalls)
			{
				//create var for location curve
				LocationCurve lc = tw.Location as LocationCurve;
				double wallLength=lc.Curve.Length;
				XYZ direction = tw.Orientation;
				double angle = direction.AngleTo(-XYZ.BasisX);
				bool iseast = Math.Abs(angle) < Math.PI/4;
				
				//test wall direction
				if(iseast)
				{
					//filter placement direction
					if(lc.Curve.GetEndPoint(0).Y - lc.Curve.GetEndPoint(1).Y > 0)
					{
						wsStart.Distance = 0;
						wsEnd.Distance = (wallLength-0.5);
						//wsEnd.DistanceMeasuredFrom.Equals(0)
						WallSweep.Create(tw,wsType.Id,wsStart);
						WallSweep.Create(tw,wsType.Id,wsEnd);
					}
					else
					{
						wsStart.Distance = 0.5;
						wsEnd.Distance = wallLength;
						WallSweep.Create(tw,wsType.Id,wsStart);
						WallSweep.Create(tw,wsType.Id,wsEnd);
					}
0 Likes
Reply
1,446 Views
12 Replies
Replies (12)

jeremytammik
Autodesk
Autodesk

Dear Msweeney,

 

Thank you for your query and welcome to the Revit API discussion forum.

 

One small note on your sample code: your transaction handling will be simplified and more robust if you encapsulate it in a `using` statement:

 

http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.53

 

http://thebuildingcoder.typepad.com/blog/2012/04/using-using-automagically-disposes-and-rolls-back.h...

 

Now, to address your question:

 

Are you aware of the RevitLookup tool?

 

https://github.com/jeremytammik/RevitLookup

 

This invaluable utility enables you to explore the Revit database interactively via the API, displaying all static element properties, parameter values and relationships with other elements.

 

That would enable you to explore the database structure and relationships of a simple standard wall, and what happens when that wall is split.

 

Presumably, new elements are introduced that refer back to the original wall or replace it in some way.

 

Probably, your code just needs some small enhancement to take these additional relationships and properties into account.

 

Is the 'split element' functionality you mention the same as the 'split face' functionality mentioned in this Q&A, leading to Face.HasRegions and Face.GetRegions?

 

http://thebuildingcoder.typepad.com/blog/2011/03/many-issues-resolved.html

 

I hope this helps.

 

Best regards,

 

Jeremy



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

0 Likes

msweeneyPES
Participant
Participant

Thanks, 

 

1. Thanks for those resources, I'm fairly new to the api and c# so I'm learning and this code at the moment is largely to see if I can get this to work my plan has been to clean it up to make it work for the other directions. Those resources look amazingly helpful. 

 

2. I do have the revit lookup tool and it is amazing, I did manage to forget about it for a couple minutes though. The main difference that I find is that the "Start Parameter", "End Parameter" of the wall that was created after being split are not 0 and 0+Length of wall, they are the end of the first segment and then adding the length. (see below-from one of the walls created from the split) . Also the "Origin" point shown at the bottom seems to be the same as the original wall. So the "Split Element" tool seems to be different from that of "split faces" in that it does create a new wall. The new walls are of the same/type/category have their own elementID, uniqueID, etc. 

 

 

fullloccurvesnoop.PNGIn creating the wall sweeps with wallsweep.create - it seems like the distance supplied should be the distance along the location curve of the wall. I'm not sure how that "Start Parameter" and "End Parameter" would come into play. 

0 Likes

ViniciusKawazoe
Participant
Participant

Did anyone solve this problem? I am trying to insert reveals on a list of walls and it just fails...

When I try to insert the reveals only on the first wall of the list it works, but as soon as it tries to insert on the second wall it breaks.

0 Likes

jeremytammik
Autodesk
Autodesk

Well, if it works on the first wall in the list, that is already good news.

 

Please share your code and maybe somebody will be able to spot a problem.

  



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

0 Likes

ViniciusKawazoe
Participant
Participant

Thanks for your reply @jeremytammik !

 

I am using the following code to insert a vertical wall reveal on each corner of the walls:

 

 

static internal void AddVerticalReveals(Wall wall)
        {
            UIDocument uidoc = Uidoc;
            Document doc = uidoc.Document;

            Curve wallCurve = ((LocationCurve)wall.Location).Curve;
            double curveStart = wallCurve.GetEndParameter(0);
            double curveEnd = wallCurve.GetEndParameter(1));

            // Get the reveal profile
            ElementType wallRevealType = new FilteredElementCollector(doc)
                .OfCategory(BuiltInCategory.OST_Reveals)
                .WhereElementIsElementType()
                .Cast<ElementType>()
                .FirstOrDefault();

            if (wallRevealType != null)
            {
                var wallRevealInfo1 = new WallSweepInfo(WallSweepType.Reveal, true);
                wallRevealInfo1.DistanceMeasuredFrom = DistanceMeasuredFrom.Base;
                wallRevealInfo1.Distance = curveStart;
                wallRevealInfo1.WallSide = WallSide.Exterior;
                wallRevealInfo1.IsProfileFlipped = false;

                var wallRevealInfo2 = new WallSweepInfo(WallSweepType.Reveal, true);
                wallRevealInfo2.DistanceMeasuredFrom = DistanceMeasuredFrom.Base;
                wallRevealInfo2.Distance = curveStart;
                wallRevealInfo2.WallSide = WallSide.Interior;
                wallRevealInfo2.IsProfileFlipped = true;

                var wallRevealInfo3 = new WallSweepInfo(WallSweepType.Reveal, true);
                wallRevealInfo3.DistanceMeasuredFrom = DistanceMeasuredFrom.Top;
                wallRevealInfo3.Distance = curveEnd;
                wallRevealInfo3.WallSide = WallSide.Exterior;
                wallRevealInfo3.IsProfileFlipped = true;

                var wallRevealInfo4 = new WallSweepInfo(WallSweepType.Reveal, true);
                wallRevealInfo4.DistanceMeasuredFrom = DistanceMeasuredFrom.Top;
                wallRevealInfo4.Distance = curveEnd;
                wallRevealInfo4.WallSide = WallSide.Interior;
                wallRevealInfo4.IsProfileFlipped = false;

                WallSweep.Create(wall, wallRevealType.Id, wallRevealInfo1);
                WallSweep.Create(wall, wallRevealType.Id, wallRevealInfo2);
                WallSweep.Create(wall, wallRevealType.Id, wallRevealInfo3);
                WallSweep.Create(wall, wallRevealType.Id, wallRevealInfo4);
            }
            else
            {
                TaskDialog.Show("ERROR", "No wall reveal type was found!");
            }
        }

 

 

It works just fine if I use it only on the first item of the list:

 

//SplitWalls_EqualDivisions(walls, gap, divisions);
IList<Element> splittedWalls = SplitWalls_EqualDivisions(walls, gap, divisions);

                        for (int i = 0; i < 1; i++)
                        {
                            AddVerticalReveals(splittedWalls[i] as Wall);
                        }

 

ViniciusKawazoe_0-1603840628317.png

But if I try to run it on the complete list, it just breaks:

 

//SplitWalls_EqualDivisions(walls, gap, divisions);
IList<Element> splittedWalls = SplitWalls_EqualDivisions(walls, gap, divisions);

                        for (int i = 0; i < splittedWalls.Count; i++)
                        {
                            AddVerticalReveals(splittedWalls[i] as Wall);
                        }

 

 

Note: The SplitWalls_EqualDivisions method splits a wall into n equal parts, and using it without the AddVerticalReveals method works just fine.

 

I would really appreciate if someone could help me with this.

Thanks!

0 Likes

jeremytammik
Autodesk
Autodesk

Looks as if you will need to hone your developer skills a bit.

 

Debugging is an integral part of development.

 

'It just breaks' is not sufficiently precise for anyone to help you, including you yourself.

 

I would suggest running the code in the debugger and determining (and formulating) more precisely what happens.

 



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

0 Likes

ViniciusKawazoe
Participant
Participant

I definitely need to hone my developer skills! Thanks for the tip @jeremytammik !

 

As I was debugging the code, the following exception was thrown for the second wall on the list:

Autodesk.Revit.Exceptions.ArgumentException: 'wall may not host a wall sweep or reveal.
Parameter name: wall'

 Captura de tela 2020-10-28 225934.png

 

But I can't seem understand why it works on the first wall of the list, but not on the following walls...

0 Likes

jeremytammik
Autodesk
Autodesk

Congratulations on a good step forward!

 

That is a million percent more information than 'it just breaks'.

 

Next, I would suggest stepping through the same operations manually in the end user interface and seeing what happens then.

 

Maybe that will provide more information, a more precise error message, some other problem, or it might even just work.

 

Then we can see further.

  



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

0 Likes

jeremytammik
Autodesk
Autodesk

You are adding multiple wall reveals to one single wall, and the second one fails?

 

Maybe you need to regenerate in between, or even commit the transaction and start a new transaction for the second reveal:

 

https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.33

  



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

0 Likes

ViniciusKawazoe
Participant
Participant

Hi @jeremytammik !

 

You saved me! I just used a Regenerate method in between and now it is working!

 

Thank you so much for tips and attention!

0 Likes

inouizi
Participant
Participant

Hi @ViniciusKawazoe , 

Do you mind sharing the part of the code you used to get the wallRevealType? 

I am trying to add reveals on walls but I was not able to figure out how to get ElementId of the WallSweepType.

 

Thanks!!

0 Likes

ViniciusKawazoe
Participant
Participant

@inouiziunfortunately I do not have access to this code, because I do not work for the company that owns it anymore. Sorry.

0 Likes