Files
2024-12-12 09:51:40 +01:00

316 lines
12 KiB
C#

#region Copyright
//
// (C) Copyright 2010 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
// Migrated to C# by Adam Nagy
//
#endregion // Copyright
#region Imports
// Import the following name spaces in the project properties/references.
// Note: VB.NET has a slighly different way of recognizing name spaces than C#.
// if you explicitely set them in each .vb file, you will need to specify full name spaces.
using System;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection; //' specific this if you want to save typing for attributes. e.g.,
// added for Lab4.
#endregion
#region Description
// Revit Intro Lab 4
//
// In this lab, you will learn how to modify elements.
// There are two places to look at when you want to modify an element.
// (1) at each element level, such as by modifying each properties, parameters, and location.
// (2) use document methods, such as move, rorat, mirror, array and delete.
//
// for #2, document.move, rotate, etc., see from pp105 of developer guide.
//
//
// Disclaimer: minimum error checking to focus on the main topic.
//
#endregion
namespace RevitIntroCS
{
// Element Modification
//
[Transaction( TransactionMode.Automatic )]
[Regeneration( RegenerationOption.Manual )]
public class ElementModification : IExternalCommand
{
// member variables
Application _rvtApp;
Document _rvtDoc;
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements )
{
// Get the access to the top most objects.
UIApplication rvtUIApp = commandData.Application;
UIDocument rvtUIDoc = rvtUIApp.ActiveUIDocument;
_rvtApp = rvtUIApp.Application;
_rvtDoc = rvtUIDoc.Document;
// select an object on a screen. (We'll come back to the selection in the UI Lab later.)
Reference r = rvtUIDoc.Selection.PickObject( ObjectType.Element, "Pick an element" );
// we have picked something.
Element elem = r.Element;
// modify element's properties, parameters, location. use document.move, rotation, mirror.
// In eailer lab, CommandData command, we learned how to access to the wallType. i.e.,
// here we'll take a look at more on the topic of accessing to elements in the interal rvt project database.
// (1) element level modification
//ModifyElementPropertiesWall(elem)
ModifyElementPropertiesDoor( elem );
_rvtDoc.Regenerate();
// select an object on a screen. (We'll come back to the selection in the UI Lab later.)
Reference ref2 = rvtUIDoc.Selection.PickObject( ObjectType.Element, "Pick another element" );
// we have picked something.
Element elem2 = ref2.Element;
// (2) you can also use document level move, rotation, mirror.
ModifyElementByDocumentMethods( elem2 );
return Result.Succeeded;
}
//
// A sampler function to demonstrate how to modify an element through its prooperties.
// Using a wall as an example here.
//
public void ModifyElementPropertiesWall( Element elem )
{
// Constant to this function.
// this is for wall. e.g., "Basic Wall: Exterior - Brick on CMU"
// you can modify this to fit your need.
//
const string wallFamilyName = "Basic Wall";
const string wallTypeName = "Exterior - Brick on CMU";
const string wallFamilyAndTypeName = wallFamilyName + ": " + wallTypeName;
// for simplicity, we assume we can only modify a wall
if( !( elem is Wall ) )
{
TaskDialog.Show( "Revit Intro Lab", "Sorry, I only know how to modify a wall. Please select a wall." );
return;
}
Wall aWall = ( Wall ) elem;
string msg = "Wall changed: " + "\n" + "\n";
//keep the message to the user.
// (1) change its family type to a different one.
// To Do: change this to enhance import symbol later.
//
Element newWallType = ElementFiltering.FindFamilyType( _rvtDoc, typeof( WallType ), wallFamilyName, wallTypeName, null );
if( newWallType != null )
{
aWall.WallType = ( WallType ) newWallType;
msg = msg + "Wall type to: " + wallFamilyAndTypeName + "\n";
}
//TaskDialog.Show("Revit Intro Lab", msg)
// (2) change its parameters.
// as a way of exercise, let's constrain top of the wall to the level1 and set an offset.
// find the level 1 using the helper function we defined in the lab3.
Level level1 = ( Level ) ElementFiltering.FindElement( _rvtDoc, typeof( Level ), "Level 1", null );
if( level1 != null )
{
aWall.get_Parameter( BuiltInParameter.WALL_HEIGHT_TYPE ).Set( level1.Id );
// Top Constraint
msg = msg + "Top Constraint to: Level 1" + "\n";
}
// hard coding for simplisity here.
double topOffset = mmToFeet( 5000.0 );
// Top Offset Double
aWall.get_Parameter( BuiltInParameter.WALL_TOP_OFFSET ).Set( topOffset );
// Structural Usage = Bearing(1)
aWall.get_Parameter( BuiltInParameter.WALL_STRUCTURAL_USAGE_PARAM ).Set( 1 );
// Comments - String
aWall.get_Parameter( BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS ).Set( "Modified by API" );
msg = msg + "Top Offset to: 5000.0" + "\n";
msg = msg + "Structural Usage to: Bearing" + "\n";
msg = msg + "Comments added: Modified by API" + "\n";
//TaskDialog.Show("Revit Intro Lab", msg)
// (3) Optional: change its location, using location curve
// LocationCurve also has move and rotation methods.
// Note: constaints affect the result.
// Effect will be more visible with disjoined wall.
// To test this, you may want to draw a single standing wall, and run this command.
//
LocationCurve wallLocation = ( LocationCurve ) aWall.Location;
XYZ pt1 = wallLocation.Curve.get_EndPoint( 0 );
XYZ pt2 = wallLocation.Curve.get_EndPoint( 1 );
// hard coding the displacement value for simility here.
double dt = mmToFeet( 1000.0 );
var newPt1 = new XYZ( pt1.X - dt, pt1.Y - dt, pt1.Z );
var newPt2 = new XYZ( pt2.X - dt, pt2.Y - dt, pt2.Z );
// create a new line bound.
Line newWallLine = _rvtApp.Create.NewLineBound( newPt1, newPt2 );
// finally change the curve.
wallLocation.Curve = newWallLine;
msg = msg + "Location: start point moved -1000.0 in X-direction" + "\n";
// message to the user.
TaskDialog.Show( "Revit Intro Lab", msg );
}
//
// A sampler function to demonstrate how to modify an element through its prooperties.
// Using a door as an example here.
//
public void ModifyElementPropertiesDoor( Element elem )
{
// Constant to this function.
// this is for a door. e.g., "M_Single-Flush: 0762 x 2032mm"
// you can modify this to fit your need.
//
const string doorFamilyName = "M_Single-Flush";
const string doorTypeName = "0762 x 2032mm";
const string doorFamilyAndTypeName = doorFamilyName + ": " + doorTypeName;
// for simplicity, we assume we can only modify a door
if( !( elem is FamilyInstance ) )
{
TaskDialog.Show( "Revit Intro Lab", "Sorry, I only know how to modify a door. Please select a door." );
return;
}
FamilyInstance aDoor = ( FamilyInstance ) elem;
string msg = "Door changed: " + "\n" + "\n";
//keep the message to the user.
// (1) change its family type to a different one.
// To Do: change this to enhance import symbol later.
//
Element newDoorType = ElementFiltering.FindFamilyType( _rvtDoc, typeof( FamilySymbol ), doorFamilyName, doorTypeName, BuiltInCategory.OST_Doors );
if( newDoorType != null )
{
aDoor.Symbol = ( FamilySymbol ) newDoorType;
msg = msg + "Door type to: " + doorFamilyAndTypeName + "\n";
}
//TaskDialog.Show("Revit Intro Lab", msg)
// (2) change its parameters.
// as a way of exercise, let's constrain top of the wall to the level1 and set an offset.
// '' find the level 1 using the helper function we defined in the lab3.
//Dim level1 As Level = ElementFiltering.FindElement(_rvtDoc, GetType(Level), "Level 1")
//If level1 IsNot Nothing Then
// aWall.Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).Set(level1.Id) '' Top Constraint
// msg = msg + "Top Constraint to: Level 1" + vbCr
//End If
//Double topOffset = mmToFeet(5000.0); //' hard coding for simplisity here.
//aWall.Parameter(BuiltInParameter.WALL_TOP_OFFSET).Set(topOffset); // '' Top Offset Double
//aWall.Parameter(BuiltInParameter.WALL_STRUCTURAL_USAGE_PARAM).Set(1) '' Structural Usage = Bearing(1)
//aWall.Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).Set("Modified by API") '' Comments - String
//msg = msg + "Top Offset to: 5000.0" + vbCr
//msg = msg + "Structural Usage to: Bearing" + vbCr
//msg = msg + "Comments added: Modified by API" + vbCr
//TaskDialog.Show("Revit Intro Lab", msg)
// (3) Optional: change its location, using location curve
// LocationCurve also has move and rotation methods.
// Note: constaints affect the result.
// Effect will be more visible with disjoined wall.
// To test this, you may want to draw a single standing wall, and run this command.
//
//Dim wallLocation As LocationCurve = aWall.Location
//Dim pt1 As XYZ = wallLocation.Curve.EndPoint(0)
//Dim pt2 As XYZ = wallLocation.Curve.EndPoint(1)
// '' hard coding the displacement value for simility here.
//Dim dt As Double = mmToFeet(1000.0)
//Dim newPt1 = New XYZ(pt1.X - dt, pt1.Y - dt, pt1.Z)
//Dim newPt2 = New XYZ(pt2.X - dt, pt2.Y - dt, pt2.Z)
// '' create a new line bound.
//Dim newWallLine As Line = _rvtApp.Create.NewLineBound(newPt1, newPt2)
// '' finally change the curve.
//wallLocation.Curve = newWallLine
//msg = msg + "Location: start point moved -1000.0 in X-direction" + vbCr
// message to the user.
TaskDialog.Show( "Revit Intro Lab", msg );
}
//
// A sampler function that demonstrates how to modify an element through document methods.
//
public void ModifyElementByDocumentMethods( Element elem )
{
string msg = "The element changed: " + "\n" + "\n";
//keep the message to the user.
// try move
double dt = mmToFeet( 1000.0 );
// hard cording for simplicity.
XYZ v = new XYZ( dt, dt, 0.0 );
_rvtDoc.Move( elem, v );
msg = msg + "move by (1000, 1000, 0)" + "\n";
// try rotate: 15 degree around z-axis.
var pt1 = XYZ.Zero;
var pt2 = XYZ.BasisZ;
Line axis = _rvtApp.Create.NewLineBound( pt1, pt2 );
_rvtDoc.Rotate( elem, axis, Math.PI / 12.0 );
msg = msg + "rotate by 15 degree around Z-axis" + "\n";
// message to the user.
TaskDialog.Show( "Revit Intro Lab", msg );
}
#region Helper Functions
//=============================================
// Helper Functions
//=============================================
// convert millimeter to feet
//
public double mmToFeet( double mmVal )
{
// * 0.00328;
return mmVal / 304.8;
}
#endregion
}
}