Generate 3d view that uses Pickbox as a sectionbox

Generate 3d view that uses Pickbox as a sectionbox

Anonymous
Not applicable
1,161 Views
2 Replies
Message 1 of 3

Generate 3d view that uses Pickbox as a sectionbox

Anonymous
Not applicable

Hi All,

This is my first post and my first code in Macro, I have been googling and looking in online RevitAPI docs to solve my issue but no success.  The code works but with issue that i want to resolve:

 

1. it doesn't allow me to generate 3d if i don't pickbox from lower-left to upper right of the Planview so i just catch it as exception(maybe because of the behavior of the pickedbox). i wonder if there is another way to do what i intended to do.

2. if there's any way to generate new 3d and replace the previously created one and use it's view settings to the new one.

 

thanks in advance

here is my code(sorry if its not looking good)

note: credits to rushfort tools for this idea 

 

public void PickBox()
		{
			UIDocument uiDoc = Application.ActiveUIDocument;
			
			Document doc = uiDoc.Document;
			
			//get Activeview plan properties
			View activeView = doc.ActiveView;
	
			try
			{
					PickedBox pick = uiDoc.Selection.PickBox(PickBoxStyle.Directional);
					BoundingBoxXYZ pickBox = new BoundingBoxXYZ();
					pickBox.Min = pick.Min;
					pickBox.Max = pick.Max;
			
		
				if (activeView is ViewPlan ) 
				{
					using (Transaction trans = new Transaction(doc,"PikBox"))
					{
						trans.Start();
							View3D threeD = null;
						
									//get active view view range
									ViewPlan plan = activeView as ViewPlan;
									PlanViewRange vRange = plan.GetViewRange();
									
									//get top and bottom level
									Level bottomlvl = doc.GetElement(vRange.GetLevelId(PlanViewPlane.BottomClipPlane)) as Level;
									Level toplvl = doc.GetElement(vRange.GetLevelId(PlanViewPlane.TopClipPlane)) as Level;
									
									//get offset from level
									double bottomOffset = vRange.GetOffset(PlanViewPlane.BottomClipPlane);
									double topOffset = vRange.GetOffset(PlanViewPlane.TopClipPlane);
								
									
									//getviewfamilytype
									ViewFamilyType vType = new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType))
											.WhereElementIsElementType()
											.Cast<ViewFamilyType>()
											.First(x => x.ViewFamily == ViewFamily.ThreeDimensional);
								if(pickBox != null)
								{
									//create3d
									threeD = View3D.CreateIsometric(doc, vType.Id);
										if(!threeD.IsSectionBoxActive)
										{
											threeD.IsSectionBoxActive = true;
										}
									
										//get section box of new 3dview and set the sectionbox using pickbox Min and Max X,Y values
										//then use the view activeview viewrange offset for Min and Max Z values
										BoundingBoxXYZ section = threeD.GetSectionBox();
										XYZ min = null;
										XYZ max = null;
										if(toplvl != doc.GetElement(PlanViewRange.LevelAbove) && bottomlvl != doc.GetElement(PlanViewRange.LevelBelow))
										{
												min = section.Min = new XYZ(pickBox.Min.X, pickBox.Min.Y, bottomlvl.ProjectElevation + bottomOffset);
												max = section.Max = new XYZ(pickBox.Max.X, pickBox.Max.Y, toplvl.ProjectElevation + topOffset);
										}
										
										else if (toplvl == doc.GetElement(PlanViewRange.LevelAbove) || toplvl == doc.GetElement(PlanViewRange.Unlimited))
										         {
										         	min = section.Min = new XYZ(pickBox.Min.X, pickBox.Min.Y, bottomlvl.ProjectElevation + bottomOffset);
													max = section.Max = new XYZ(pickBox.Max.X, pickBox.Max.Y, bottomlvl.ProjectElevation + 10);
										         }
										else if (bottomlvl == doc.GetElement(PlanViewRange.LevelBelow) || bottomlvl == doc.GetElement(PlanViewRange.Unlimited))
												{
												
										         	min = section.Min = new XYZ(pickBox.Min.X, pickBox.Min.Y, toplvl.ProjectElevation - 10);
													max = section.Max = new XYZ(pickBox.Max.X, pickBox.Max.Y, toplvl.ProjectElevation + topOffset);
												}
									
										//create new bbox and use new generated min and max values
										BoundingBoxXYZ new_bbox = new BoundingBoxXYZ();
										new_bbox.Min = min;
										new_bbox.Max= max;
										//set the new section box of 3d from new bbox
										threeD.SetSectionBox(new_bbox);
									
										//hide scope box
										Categories categories = doc.Settings.Categories;
										Category scopeBox = categories.get_Item(BuiltInCategory.OST_VolumeOfInterest);
										ElementId cat = scopeBox.Id;
										
										threeD.SetCategoryHidden(cat, true);
										
										//set graphic settings
										threeD.get_Parameter( BuiltInParameter.VIEW_DETAIL_LEVEL ).Set( 3 );
						      			threeD.get_Parameter( BuiltInParameter.MODEL_GRAPHICS_STYLE ).Set( 3 );
						      			
						      			//hide importcategory
						      			if(!threeD.AreImportCategoriesHidden)
						      			{
						      				threeD.AreImportCategoriesHidden = true;
						      			}
									}
								else
								{
									throw new Exception("draw from 	LOWER LEFT to UPPER LEFT");
								}
									
						trans.Commit();
						
						uiDoc.ActiveView = threeD;
					}//end of transaction
	
				}
				else
				{
					TaskDialog.Show("Error", "View is not Plan View");
				}//end of first condition
					
			} 
			catch (Exception)
			{
				
				TaskDialog.Show("Error", "draw from LOWER LEFT to UPPER RIGHT");
			}//pick exception
		}
0 Likes
Accepted solutions (1)
1,162 Views
2 Replies
Replies (2)
Message 2 of 3

Moustafa_K
Collaborator
Collaborator
Accepted solution

Hi,

Basically, like you said it won't allow drawing boundingbox from any other clicks except from bottom left to top right, but this is because the bottom left coordinates is less than the top right coordinates.

hence,

You need to ensure that the bounding box initialized correctly
and we do not know if the user started clipping from top left to bottom right
or from top right to bottom left
or from bottom left to top right
or from bottom right to top left
all in all bounding box XYZ maximum point must be bigger than minimum point otherwise you would get an empty bounding box.

 

so try to switch the x and Y values to ensure the minimum is the minimum point and the max is the maximum point

something like this:

if (pickedbox.Max.X < pickedbox.Min.X)
				{
					maxx = pbox.Min.X;
					minx = pbox.Max.X;
				}

hope that helps

 

 

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
Message 3 of 3

Anonymous
Not applicable

Hi @Moustafa_K  that make sense now. It works i just need little bit of massaging to my code. I can go from here. 

 

Thanks a lot!

0 Likes