Skip to content

Instantly share code, notes, and snippets.

@BimManager
Last active June 22, 2023 22:30
Show Gist options
  • Save BimManager/80de58d35a753be892285747999c1c35 to your computer and use it in GitHub Desktop.
Save BimManager/80de58d35a753be892285747999c1c35 to your computer and use it in GitHub Desktop.
RevitAPI
Revit API Exploration Tools
RevitLookup
BipChecker
AdnRevitApiLabsXtra
RevitPythonShell
Revit SDK
the_building_coder_samples
// how to embed a page into a Revit add-in
use the WPF User Control Library type
if (elementId != ElementId.InvalidElementId)
Autodesk.Revit.UI.UIApplication uiapp;
Autodesk.Revit.UI.UIControlledApplication uicapp;
Autodesk.Revit.UI.Application app;
UIDocument uidoc;
UIDocument uidoc = new UIDocument(doc);
Document doc;
EVENTS
Application level events
Application
ControlledApplication
DB events and UI events
Application and Document
UIApplication
// Transactions
using (Transaction trxn = new Transaction(doc)) {
TransactionStatus status = trxn.Start("trxn description");
// do something here
trxn.Commit();
}
static class Globals {
public const String kApplicationName = "DockablePane";
public const String kTabName = "Fohlio";
public const String kPanelName = "DockablePane Panel";
public static Guid kPanelGuid = new Guid();
}
static class ReflectionData {
public static String GetAssemblyPath() {
if (null == _assemblyPath) {
_assemblyPath = Path.GetDirectoryName(
Assembly.GetExecutingAssembly().Location);
}
return _assemblyPath;
}
public static String GetAssemblyFullName() {
if (null == _assemblyFullName) {
_assemblyFullName = Assembly.GetExecutingAssembly().Location;
}
return _assemblyFullName;
}
public static String GetApplicationResourcesPath() {
if (null == _resourcesPath) {
_resourcesPath = GetAssemblyPath + "\\Resources\\";
}
return _resourcesPath;
}
private static String _assemblyPath = null;
private static String _assemblyFullName = null;
private static String _resourcesPath = null;
}
static class Logging {
public static void LogMessage(String message, int level = 0) {
String log = String.Format("{0:MM-dd-yyyy HH:mm:ss} {1}", DateTime.Now, message);
Console.WriteLine(log);
Debug.WriteLine(log);
if (level > 0) TaskDialog.Show("Revit Logging", log);
}
public static void AddLogFile(String filepath) {
#if DEBUG
Debug.Listeners.Add(new TextWriterTraceListener(filepath + ".trace"));
Debug.AutoFlush = true;
#else
Trace.Listeners.Add(new TextWriterTraceListener(filepath + ".debug"));
Trace.AutoFlush = true;
#endif
}
}
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
Document doc =
commandData.Application.ActiveUIDocument.Document;
Selection selection =
commandData.Application.ActiveUIDocument.Selection;
Reference r = selection.PickObject(ObjectType.Element);
SpatialElement spElem = doc.GetElement(r) as SpatialElement;
SpatialElementBoundaryOptions boundaryOptins =
new SpatialElementBoundaryOptions
{ SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center };
IList<double> areas = new List<double>();
foreach(IList<BoundarySegment> bndSegments in spElem.GetBoundarySegments(boundaryOptins))
{
areas.Add(CalculateArea(bndSegments));
}
TaskDialog.Show("Result:", string.Format("Area={0}", areas.Sum()));
return Result.Succeeded;
}
private static double CalculateArea(IList<BoundarySegment> segments)
{
IList<XYZ> vertices = segments
.Select<BoundarySegment, XYZ>(s => s.GetCurve().GetEndPoint(0))
.ToList();
double area = 0;
for (int i = 0, j; i < vertices.Count; i++)
{
j = i + 1;
area = area + vertices[i].X * vertices[j].Y;
area = area + vertices[i].Y * vertices[j].X;
}
return area;
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace Revit.SDK.Samples.HelloRevit.CS
{
[Transaction(TransactionMode.Manual)]
public class Command : IExternalCommand
{
public Result Execute(ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
Document doc =
commandData.Application.ActiveUIDocument.Document;
// Get access to all the TextNote Elements
FilteredElementCollector collectorUsed
= new FilteredElementCollector(doc);
ICollection<ElementId> textNotes
= collectorUsed.OfClass(typeof(TextNote))
.ToElementIds();
foreach (ElementId textNoteid in textNotes)
{
TextNote textNote = doc.GetElement(
textNoteid) as TextNote;
Transaction trans = new Transaction(doc);
trans.Start("ChangeParam");
// Create a duplicate
Element ele =
textNote.TextNoteType.Duplicate("ADSK_NewTextNoteType");
TextNoteType noteType = ele as TextNoteType;
if (null != noteType)
{
// Just for example sake, change the font parameter
noteType.get_Parameter("Text Font").Set("Arial Narrow");
}
trans.Commit();
}
return Result.Succeeded;
}
}
}
REVIT DESIGN AUTOMATION
it is an engine that can run add-ins in the cloud
1. upload data to a cloud storage (forge data services recommend)
2. send a link to the data to Forge DA
CLOUD -------> FORGE DA (runs your Revit add-in on the data provided)
<-------
V3 HTTP ENDPOINTS
/workitems (function call)
/activities (function definition)
/appbundles (shared library)
/engines (instruction set)
public void ElementOverride()
{
Document doc = this.ActiveUIDocument.Document;
UIDocument uidoc = this.ActiveUIDocument;
ElementId id = uidoc.Selection.PickObject(ObjectType.Element,"Select an element").ElementId;
OverrideGraphicSettings ogs = new OverrideGraphicSettings();
ogs.SetProjectionLineColor(new Color(0,255,0));
using (Transaction t = new Transaction(doc,"Set Element Override"))
{
t.Start();
doc.ActiveView.SetElementOverrides(id, ogs);
t.Commit();
}
}
class App : IExternalApplication
{
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
string assemblyPath = Assembly.GetExecutingAssembly().Location;
string panelName = "Tekta";
// Produce a new ribbon panel
RibbonPanel ribbonPanel =
application.CreateRibbonPanel(Tab.AddIns, panelName);
// Add a push button to the ribbon panel
PushButton pushButton = ribbonPanel
.AddItem(new PushButtonData
("Splitter", "Splitter", assemblyPath, "TektaRevitPlugins.SplitterCommand"))
as PushButton;
// Set the image depicted on the button
pushButton.LargeImage = BmpImageSource("TektaRevitPlugins.Resources.axe_32x32.png");
pushButton.Image = BmpImageSource("TektaRevitPlugins.Resources.axe_16x16.png");
return Result.Succeeded;
}
#region Helper Methods
System.Windows.Media.ImageSource BmpImageSource(string embeddedPath)
{
Stream stream = this.GetType().Assembly.GetManifestResourceStream(embeddedPath);
var decoder = new System.Windows.Media.Imaging.PngBitmapDecoder
(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
return decoder.Frames[0];
}
#endregion
}
class ExternalEventHandler : IExternalEventHandler {
static ExternalEventHandler _instance;
ExternalEvent _externalEvent;
Action<UIApplication, Object> _callback;
Object _data;
public static ExternalEventHandler Instance {
get {
if (null == _instance) _instance = new ExternalEventHandler();
return _instance;
}
}
public ExternalEvent ExternalEvent {
get {
if (null == _externalEvent) _externalEvent = ExternalEvent.Create(this);
return _externalEvent;
}
}
public void RegiserCallback(Action<UIApplication, Object> callback,
Object data) {
_callback = callback;
_data = data;x
}
public void Execute(UIApplication app) {
if (_callback != null) _callback.Invoke(app, _data);
}
public String GetName() { return "External Event Handler"; }
ExternalEventInstance() {}
}
// 1. Create the event in OnStartup()
ExternalEventHandler.Instance.ExternalEvent;
// 2. Register a callback function
ExternalEventHandler.Instance.RegisterCallback((data) => { ... }, someData);
// 3. Queue the event
ExternalEventHandler.Instance.ExternalEvent.Raise();
// Filtering by means of the Revit API
RoomFilter roomFilter = new RoomFilter();
AreaFilter areaFilter = new AreaFilter();
ExtensibleStorageFilter storageFilter = new ExtensibleStorageFilter();
ElementWorksetFilter worksetFilter;
FamilyInstanceFilter famInstFilter;
FamilySymbolFilter famSymFilter;
// Dealing with materials
//Materials materials = doc.Settings.Materials; no longer supported
Materials materials = elementsCollector
.WherePasses(new ElementClassFilter(typeof(Material)) //.OfClass(typeof(Material))
.ToElements()
.Cast<Material>()
.ToList();
// Only for category.HasMaterialQuantities();
element.GetMaterialIds(bool returnPaintMaterials);
element.GetMaterialVolume(ElementId materialId);
element.GetMaterialArea(ElementId materialId, bool isPaintMaterial);
FilteredElementCollector collector = new FilteredElementCollector();
IList<Element> materials = collector.WherePasses(new ElementClassFilter(typeof(Material));
ElementCategoryFilter categoryFilter = new ElementCategoryFilter(BuiltInCategory);
ElementClassFilter classFilter = new ElementClassFilter(typeof(Level));
ElementIsElementTypeFilter typeFilter = new ElementIsElementTypeFilter();
ElementLevelFilter lvlFilter = new ElementLevelFilter(ElementId);
ElementMulticategoryFilter multicategoryFilter =
new ElementMulticategoryFilter(ICollection<BuiltInCategory>);
ElementIntersectsFilter intersectionFilter = new ElementIntersectsFilter();
ElementIntersectsElementFilter intersectionFilter = new ElementIntersectsElementFilter(Element);
ElementIntersectsSolidFilter solidIntersectionFilter = new ElementIntersectsSolidFilter(Solid);
ElementDesignOptionFilter designOptionFilter = new ElementDesignOptionFilter(ElementId);
ElementPhaseStatusFilter phaseStatusFilter = new ElementPhaseStatusFilter(ElementId phaseId, ICollection<ElementOnPhaseStatus> phaseStatuses);
FilterRule fr = ParameterFilterRuleFactory.CreateEquals(ElementId, string, bool); // FilterRule factory
ElementParameterFilter paramFilter = new ElementParameterFilter(fr);
collector.WherePasses(paramFilter);
FilterNumericLess less;
FilterNumericLessOrEqual lessEqual;
FilterNumericGreater greater;
FilterNumericGreaterOrEqual greaterEqual;
FilterNumericEquals equals;
ExclusionFilter exclusionFilter = new ExclusionFilter();
// Filtering by means of the Revit API
/*
** Quick filters operate on only the ElementRecord, a low-memory class
** which has a limited interface to read element properties.
** Slow filters require that the Element be obtained and expanded in memory.
**
*/
RoomFilter roomFilter = new RoomFilter();
AreaFilter areaFilter = new AreaFilter();
ExtensibleStorageFilter storageFilter = new ExtensibleStorageFilter();
ElementWorksetFilter worksetFilter;
FamilyInstanceFilter famInstFilter;
FamilySymbolFilter famSymFilter;
// Dealing with materials
//Materials materials = doc.Settings.Materials; no longer supported
FilteredElementCollector collector = new FilteredElementCollector();
Materials materials = collector
.WherePasses(new ElementClassFilter(typeof(Material))) //.OfClass(typeof(Material))
.ToElements()
.Cast<Material>()
.ToList();
// Only for category.HasMaterialQuantities();
element.GetMaterialIds(bool returnPaintMaterials);
element.GetMaterialVolume(ElementId materialId);
element.GetMaterialArea(ElementId materialId, bool isPaintMaterial);
ElementCategoryFilter categoryFilter = new ElementCategoryFilter(BuiltInCategory);
ElementClassFilter classFilter = new ElementClassFilter(typeof(Level));
ElementIsElementTypeFilter typeFilter = new ElementIsElementTypeFilter();
ElementLevelFilter lvlFilter = new ElementLevelFilter(ElementId);
ElementMulticategoryFilter multicategoryFilter =
new ElementMulticategoryFilter(ICollection<BuiltInCategory>);
ElementIntersectsFilter intersectionFilter = new ElementIntersectsFilter();
ElementIntersectsElementFilter intersectionFilter = new ElementIntersectsElementFilter(Element);
ElementIntersectsSolidFilter solidIntersectionFilter = new ElementIntersectsSolidFilter(Solid);
ElementDesignOptionFilter designOptionFilter = new ElementDesignOptionFilter(ElementId);
PrimaryDesignOptionMemberFiler primaryDesignOptionFilter =
new PrimaryDesignOptionMemberFilter();
ElementPhaseStatusFilter phaseStatusFilter =
new ElementPhaseStatusFilter(
ElementId phaseId,ICollection<ElementOnPhaseStatus> phaseStatuses);
FilterRule fr = ParameterFilterRuleFactory.CreateEquals(ElementId, string, bool); // FilterRule factory
ElementParameterFilter paramFilter = new ElementParameterFilter(fr);
collector.WherePasses(paramFilter);
FilterNumericLess less;
FilterNumericLessOrEqual lessEqual;
FilterNumericGreater greater;
FilterNumericGreaterOrEqual greaterEqual;
FilterNumericEquals equals;
ExclusionFilter exclusionFilter = new ExclusionFilter();
// OPTIMISATIONS
FilteredElementCollector collector
= new FilteredElementCollector(doc)
.OfCategory(BuiltInCategory.OST_Doors)
.OfClass(typeof(FamilySymbol));
foreach (FamilySymbol fs in collector) {
Family family = fs.Family;
}
// BASICS
// Autodesk.Viewing.Document
// Autodesk.Viewing.BubbleNode
// Autodesk.Viewing.Model
// Autodesk.Viewing.InstanceTree is an object for query nodes.
const tree = model.getInstanceTree();
tree.enumNodeChildren(tree.getRootId(), (nodeId) => {
tree.enumNodeFragments(nodeId, (fragId) => {
const fragProxy = viewer.impl.getRenderProxy(model, fragId);
}, true); // recursive: true
}, true); // recursive: true
viewer.impl.scene.add(mesh);
viewer.impl.sceneUpdated(true); // update things that have been changed
viewer.impl.invalidate(true); // reprocess the entire scene
// In case of materials, using invalidated() is preferable because
// the material list is outside the scene.
viewer.impl.getMaterials().addMaterial('superMaterial', material, true);
viewer.impl.matman().addMaterial('superMaterial', material, true);
viewer.impl.getFragmentProxy(model, fragId);
viewer.setThemingColor(dbId, new THREE.Vector4(1, 0, 0, 1));
function setMaterial(viewer, dbIds, material) {
const model = viewer.model;
model.unconsolidate();
const tree = model.getInstanceTree();
const frags = model.getFragmentList();
}
// Autodesk.Viewing.Model model;
const model = NOP_VIEWER.model;
model.getInstanceTree();
model.getFragmentList();
model.getGeometryList();
model.getGeomScenes();
model.getData(); // geometry data
model.getDocumentNode();
model.getRoot();
model.getRootId();
model.getMetadata(itemName, subitemName, defaultValue);
model.getPropertyDb();
model.getProperties(dbId, onSuccessCallback, onErrorCallback);
model.getProperties2(dbId, onSuccessCallback, onErrorCallback, {
needsExternalId: false
});
model.getBulkProperties(dbIds, options, onSuccessCallback, onErrorCallback);
model.getBulkProperties2(dbIds, options, onSuccessCallback, onErrorCallback);
model.getPropertySetAsync(dbIds, options)
.then(function(propertySet) {
propertySet.forEach(function(key, properties) {
/* ,,, */
});
});
// PROPERTY OBJECT
{
attributeName: 'Category',
dbId: 42,
displayCategory: '__document__',
displayName: 'Category',
displayValue: 'Revit Document',
hidden: 1,
parentName: 'Model',
precision: 0,
type: 20,
unit: null
}
// HOW TO OPEN A DOCUMENT
Autodesk.Viewing.Viewer3D.loadModel(urn, options,
onSuccessCallback, onFailureCallback);
Autodesk.Viewing.Viewer3D.loadDocumentNode(
Autodesk.Viewing.Document doc, Autodesk.Viewing.BubbleNode manifestNode,
options);
// METHOD A
Autodesk.Viewing.Document.load(
modelUrn, onDocumentLoadedSuccess, onDocumentLoadedFailure);
function onDocumentLoadedSuccess(doc) {
const defaultModel = doc.getRoot().getDefaultModel();
viewer.loadDocumentNode(doc, defaultModel); // wraps loadModel()
// SVF2 models
const url = doc.getViewablePath(defaultModel);
viewer.loadModel(url, { acmSessionId: doc.getAcmSessionId(url) });
}
function onDocumentLoadedFailure() {}
// METHOD B
// METHOD C
let doc = new Autodesk.Viewing.Document(dataJSON, path, acmSession);
// acmSession is required to load a SVF2 modeil
fetch('http://localhost:3000/api/forge/modelderivate/<urn>/manifest')
.then((res) => {
res.json().then((body) => {
doc = new Autodesk.Viewing.Document(body, 'urn:' + urn);
let defaultModel = doc.getRoot().search({
type: 'geometry', role: '3d', isMasterView: true
});
// getDefaultGeometry(searchMasterView, loadLargestView);
defaultModel = doc.getRoot().getDefaultGeometry(true);
if (manifestNodes.length > 0) {
viewer.loadDocumentNode(doc, manifestNodes[0]);
}
});
})
Autodesk.Viewing.Document.load(
modelUrn, onSuccessCallback, onFailureCallback, options); // a static method
function onSuccessCallback(doc) {
// Autodesk.Viewing.BubbleNode
const bubbleNodeRoot = doc.getRoot();
const lmvDoc = bubbleNodeRoot.lmvDocument;
}
// HOW TO REGISTER AN EXTENSION
(function() {
'use strict'
function MyExtension(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
}
MyExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
MyExtension.prototype.constructor = MyExtension;
let proto = MyExtension.prototype;
proto.load = function() {
console.log("My extension loaded!");
return true;
}
proto.unload = function() {
console.log("My extension unloaded");
return true;
}
Autodesk.Viewing.theExtensionManager.registerExtension(
'MyExtension', MyExtension);
})();
viewer.loadExtension('MyExtension')
.then((ext) => {
console.log("success");
})
.catch((err) => {
console.error(err);
});
NOP_VIEWER.isExtensionLoaded('MyExtension');
NOP_VIEWER.loadExtension('MyExtension');
NOP_VIEWER.loadExtension('Autodesk.DocumentBrowser'); // 2D & 3D viewables
NOP_VIEWER.unloadExtension('MyExtension');
// HOW TO ADD A BUTTON
viewer.loadDocumentNode(doc, items[0])
.then(function(model) {
let group = viewer.toolbar.getControl('randomName');
if (!group) {
group = new Autodesk.Viewing.UI.ControlGroup('randomName');
viewer.toolbar.addControl(group);
}
button = new Autodesk.Viewing.UI.Button('printButton');
button.setIcon('adsk-icon-layers');
button.onClick = () => {
foo(viewer);
};
button.setToolTip('Print Sheet');
group.addControl(button);
});
// added AEC data to models translated from Revit
function onDocumentLoadSuccess(doc) {
let defaultModel = doc.getRoot().getDefaultGeometry();
doc.downloadAecModelData();
viewer.loadDocumentNode(doc, defaultModel);
}
const aecData = viewer.model.getDocumentNode().getAecModelData();
// HOW TO ADD A CUSTOM GEOMETRY
// 1. Create a custom geometry
let geometry = new THREE.SphereGeometry(10, 8, 8);
let material = new THREE.MeshBasicMaterial({ color: 0x0000ff });
let mesh = new THREE.Mesh(sphereGeom, meshMaterial);
// 2. Create an overlay scene
const sceneName = 'customScene';
if (!viewer.overlays.hasScene(sceneName)) {
viewer.overlays.addScene(sceneName);
}
// 3. Add the custom geometry to the scene
viewer.overlays.addMesh(mesh, sceneName);
// 4. Do the clean-up
viewer.overlays.removeMesh(mesh, sceneName);
viewer.overlays.removeScene(sceneName);
meshMaterial.dispose();
sphereGeom.dispose();
// HOW TO QUERY THE PROPERTY DATABASE (Autodesk.Globals.PropertyDatabase)
// the function must be named userFunction
function userFunction(pdb) {
pdb.enumAttribtes(function(i, attrDef, attrRaw) {
});
pdb.enumObjects(function(dbId) {
pdb.enumObjectProperties(dbId, function(attrId, valId) {
const attrDef = pdb.getAttributeDef(attrId);
const attrVal = pdb.getAttrValue(attrId, valId);
});
});
return 42;
});
viewer.model
.getPropertyDb()
.executeUserFunction(userFunction)
.then((result) => { })
.catch((err) => console.error(err));
// Since version 7.0.0
function userFunction(pdb, userData) {
}
viewer.model
.getPropertyDb()
.executeUserFunction(userFunction, userData)
.then((result) => { })
.catch((error) => { })
// SELECTION
viewer.getSelection(); // [928, 42, 23]
viewer.select([42, 191]);
function onSelectionChanged(event) {
const dbId = event.dbIdArray[0];
if (dbId) {
NOP_VIEWER.model.getProperties(dbId, (result) => {
_externalId = result.externalId;
});
}
handleSelectionChangeed(event.fragIdsArray);
}
// ACCESSING METADATA WITHOUT THE VIEWER
// 1. GET :urn/metadata/:guid/properties
// 2. Sqlite database
// GET :urn/manifest
// sqlite> .tables
// sqlite> PRAGMA table_info(_objects_attr);
// sqlite> .schema _objects_eav
// sqlite> .headers on
// sqlite> .mode column
/*
** _objects_attr
** id | INTEGER
** name | TEXT
** category | TEXT
** data_type | INTEGER
** data_type_context | TEXT
** description | TEXT
** display_name | TEXT
** flags | INTEGER
** display_precision | INTEGER
** forge_parameter | TEXT
*/
/*
** _objects_eav
** id | INTEGER
** entity_id | INTEGER
** attribute_id | INTEGER
** value_id | INTEGER
*/
/*
** _objects_id
** id | INTEGER
** external_id | BLOB
** viewable_id | BLOB
*/
/*
** _objects_val
** id | INTEGER
** value | BLOB
*/
/* 3. Viewer-optimised database
** objects_attr.json.gz
** objects_avs.json.gz
** objects_ids.json.gz
** objects_vals.json.gz
*/
SELECT id.external_id, id.viewable_id, attr.name, attr.category, val.value
FROM (((_objects_eav AS eav JOIN _objects_attr AS attr ON eav.attribute_id = attr.id)
JOIN _objects_val AS val ON eav.value_id = val.id)
JOIN _objects_id as id ON eav.entity_id = id.id)
/*
** HOW TO FIND ALL FAMILY TYPE INSTANCES BASED ON THE TYPE'S UNIQUE ID
*/
SELECT val.value
FROM (((_objects_eav AS eav JOIN _objects_attr AS attr
ON eav.attribute_id = attr.id)
JOIN _objects_val AS val ON eav.value_id = val.id)
JOIN _objects_id as id ON eav.entity_id = id.id)
WHERE id.external_id LIKE '705%1bef'
AND attr.category LIKE '__child__';
//SELECT id.external_id, id.viewable_id, attr.name, attr.category, val.value
SELECT *
FROM (((_objects_eav AS eav JOIN _objects_attr AS attr ON eav.attribute_id = attr.id)
JOIN _objects_val AS val ON eav.value_id = val.id)
JOIN _objects_id as id ON eav.entity_id = id.id)
WHERE attr.category LIKE '__parent__'
LIMIT 5;
// SELECT ALL INFO ABOUT
SELECT * FROM (((_objects_id AS id JOIN _objects_eav AS eav ON id.id = eav.entity_id) JOIN _objects_val AS val ON val.id = eav.value_id) JOIN _objects_attr AS attr ON attr.id = eav.attribute_id) WHERE val.value = 'Furniture';
// CODE SNIPPETS
var viewer;
var objectIds = [];
function launchViewer(urn, object_id) {
objectIds = [];
objectIds.push( object_id);
var options = {
env: 'AutodeskProduction2',
api: 'streamingV2',
getAccessToken
};
Autodesk.Viewing.Initializer(options, function onInitialized() {
viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('forgeViewer'));
viewer.start();
var documentId = 'urn:' + urn;
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
}
function onDocumentLoadSuccess(doc) {
var viewables = doc.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(doc, viewables).then( async (model) => {
// Highlight the takeoff element after geometry is loaded
await Autodesk.Viewing.EventUtils.waitUntilGeometryLoaded(viewer);
viewer.isolate(objectIds);
viewer.fitToView(objectIds);
});
}
function onDocumentLoadFailure(viewerErrorCode) {
console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
}
async function getAccessToken(callback) {
const resp = await fetch('/api/forge/oauth/token');
if (resp.ok) {
const { access_token, expires_in } = await resp.json();
callback(access_token, expires_in);
} else {
alert('Could not obtain access token. See the console for more details.');
console.error(await resp.text());
}
}
/*
** VIEWER EXTENSIONS: TIPS AND TRICKS
*/
// EXTENSION LOADING
Autodesk.Viewing.theExtensionManager
.registerExtension('FooExtensionId', FooExtension);
// Method A
const viewer = new Autodesk.Viewing.GuiViewer3D(
container, { extension: ['FooExtensionId'] });
// Method B
const viewer = new Autodesk.Viewing.GuiViewer3D(container);
viewer.loadExtension('FooExtensionId');
// Method C
Autodesk.Viewing.theExtensionManager.registerExternalExtension(
'FooExtensionId', 'https://foo.fohlio.com/public/FooExtension.js');
const viewer = new Autodesk.Viewing.GuiViewer3D(
container, { extensions: ['FooExtensionId'] });
// PASSING OPTIONS TO EXTENSIONS
viewer.loadExtension('FooExtensionId', { passcode: 'Fido' });
// ...
constructor(viewer, options) {
super(viewer, options);
console.log(options.passcode); // 'Fido'
}
// ...
const viewer = new Autodesk.Viewing.GuiViewer3D(container, {
extensions: ['FooExtensionId'],
fooExtOptions: { passcode: 'Fido' }
});
// ...
constructor(viewer, options) {
super(viewer, options);
console.log(options.fooExtOptions); // { passcode: 'Fido' }
}
// ...
// ASYNC LOADING AND UNLOADING
async load() {
const loadScript = (src) => new Promise(function(resolve, reject) {
const el = document.createElement('script');
el.src = src;
el.onload = resolve;
el.onerror = reject;
document.head.appendChild(el);
});
const loadCSS = (href) => new Promise(function(resolve, reject) {
const el = document.createElement('link');
el.rel = 'stylesheet';
el.href = href;
el.onload = resolve;
el.onerror = reject;
document.head.appendChild(el);
});
await Promise.all([
this.viewer.loadExtension('SomeOtherExtension'),
loadScript('https://foo.fohlio.com/public/js/foo.js'),
loadCSS('https://foo.fohlio.com/public/css/foo.css')
]);
return true;
}
// EXTENSION STATE
class FooExtension extends Autodesk.Viewing.Extension {
// ...
getState(state) {
state['fooExtState'] = state['fooExtState'] || {};
state['fooExtState'].passcode = 'Fido';
}
restoreState(state) {
const fooExtState = state['fooExtState'] || {};
this.passcode = fooExtState.passcode || '';
}
// ...
}
// PROXYING THE FORGE VIEWER
const options = {
shouldInitializeAuth: false,
endpoint: 'http://localhost:3000/forge/api/viewer-proxy',
};
const FORGE_HOST = 'https://developer.api.autodesk.com';
router.use('/viewer-proxy/*', function(req, res) {
try {
if (userAllowedToAccessResource(req)) {
const headers = {
'Authorization': 'Bearer ' + actualForgeToken
};
fetch(FORGE_HOST + req.path, { headers })
.then((res) => { return res.buffer })
.then((buffer) => { return res.send(buffer); })
.catch((err) => { res.status(400).send(err);});
} else {
res.status(401).end();
}
} catch (err) {
console.error(err);
res.status(500).send(err.message);
}
});
/*
** LABELING
*/
// HTML ELEMENTS on top of the model (SVG, DIV)
// AEC DATA
doc.downloadAecModelData();
// viewports
// let cameraPos = viewports[0].cameraOrienataion;
// cameraPos[0] - cameraPos[2] => the camera's forward direction
// cameraPos[3] - cameraPos[5] => the camera's up vector
// cameraPos[6] - cameraPos[8] => the camera's origin (eye point)
// let viewportPos = viewports[0].viewportPosition;
// viewportPos[0] - viewportPos[2] => the viewport's low-left corner
// viewportPos[3] - viewportPos[5] => the viewport's upper-right corner
// DATA VISUALIZATION API
const dataVizExt = await viewer.loadExtension('Autodesk.DataVisualization');
// modelInfo.getRoomList().then((rooms) => {});
// modelInfo.getLevel(room); // returns string
// modelInfo.getLevelRoomsMap().then((levelRooms) => {});
function createHeatmapForRooms(dataVizExt, model) {
const modelInfo = new Autodesk.DataVisualization
.Core.ModelStructureInfo(model);
let promise = modelInfo.getRoomList();
promise = promise
.then((rooms) => {
const devices = [];
rooms.forEach((room) => {
const centroid = room.bounds.getCenter();
devices.push({
id: room.name,
position: { x: centroid.x, y: centroid.y, z: room.bounds.min.z },
sensorType: ['temperature', 'humidity']
});
});
return Promise.resolve(devices);
});
promise.then((devices) => {
modelInfo.generateSurfaceShadingData(devices)
.then((shadingData) => {
dataVizExt.setupSurfaceShading(model, shadingData)
.then(() => {
const sensorColors = [ 0x0000ff, 0x00ff00, 0xff0000 ];
const sensorType = 'temperature';
dataVizExt.registerSurfaceShadingColors(sensorType, sensorColors);
function getSensorValue(surfaceShadingPoint, sensorType) {
const deviceId = surfaceShadingPoint.id;
let sensorValue = readSensorValue(deviceId, sensorType);
const maxSensorValue = getMaxSensorValue(sensorType);
const minSensorValue = getMinSensorValue(sensorType);
sensorValue = (sensorValue - minSensorValue) /
(maxSensorValue - sensorValue);
return clamp(sensorValue, 0.0, 1.0);
}
modelInfo.getLevelRoomsMap()
.then((levelRooms) => {
Object.keys(levelRooms).forEach((levelName) => {
dataVizExt.renderSurfaceShading(
levelName, sensorType, getSensorValue);
});
});
});
});
});
}
// THREE.js
// mesh => geometry + material
// scene => meshes + lights
// renderScene => scene + camera
// Prefer THREE.BufferGeometry to THREE.Geometry;
function essentialSetups() {
const scene = new THREE.Scene();
const axes = new THREE.AxisHelper(20);
scene.add(axes);
let geometry = new THREE.PlaneGeometry(60, 20, 1, 1);
geometry = new THREE.CubeGeometry(42, 42, 42);
geometry = new THREE.SphereGeometry(4, 20, 20);
let material = new THREE.MeshBasicMaterial({
color: 0xff0000, wireframe: true
});
material = new THREE.MeshLambertMaterial({
color: 0xff0000
});
let mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true; // only for MeshLambertMaterials
mesh.position.set(10, 10, 0);
scene.add(mesh);
const spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(10, 10, 20);
scene.add(spotLight);
const camera = new THREE.PerspectiveCamera(
45, window.innderWidth / window.innerHeight, 0.1, 1000);
camera.position.set(-30, 40, 30);
camera.lookAt(scene.position);
const renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0xeeeeee));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true; // for calculating shadows
function renderScene() {
requestAnimationFramer(renderScene);
renderer.render(scene, camera);
}
$('#viewer').append(renderer.domElement);
renderScene();
}
// THREE.Scene
const scene = new THREE.Scene();
scene.add(mesh);
scene.children;
scene.getChildByName(name);
scene.remove(mesh);
scene.traverse((child) => {
if (child instanceof THREE.Mesh) ;
});
scene.fog = new THREE.Fog(0xffffff, 0.015, 100);
scene.overrideMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 });
// THREE.Geometry
// A geometry is a collection of points (vertices) and a number of faces
// connecting all those points
// THREE.SphereGeometry
// THREE.CubeGeometry
const vertices = [
new THREE.Vector3(1, 3, 1),
new THREE.Vector3(-1, 3, 1),
new THREE.Vector3(0, 0, 0),
];
const faces = [
new THREE.Face3(0, 1, 2); // creates a face by joining vertice 0, 1, and 2
];
/* THREE.Geometry IS OBSOLETE; USE THREE.BufferGeometry */
let geometry = THREE.Geometry();
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeCentroids();
geometry.mergeVertices();
function renderScene() {
mesh.geometry.vertices = vertices;
mesh.geometry.verticesNeedUpdate = true;
mesh.geometry.computeFaceNormals();
}
// THREE.Mesh (Only THREE.mesh can be rendered)
const mesh = new THREE.Mesh(geometry, material);
const meshes = THREE.SceneUtils.createMultiMaterialObject(geometry, materials);
const line = new THREE.Line(geometry, new THREE.LineBasicMaterial({
color: 0xff0000, linewidth: 2
}));
// Method A
mesh.position.x = 42;
mesh.position.y = 42;
mesh.position.z = 42;
mesh.rotation.x = 0.5 * Math.PI;
mesh.scale.x = 1.2;
mesh.translateX(10); // move the mesh relative to its current positon
mesh.translateY(10);
mesh.translateZ(10);
// Method B
mesh.position.set(42, 42, 42);
mesh.rotation.set(0.5 * Math.PI, 0, 0);
mesh.scale.set(1.2, 0, 0);
// Method 3
mesh.position = new THREE.Vector3(42, 42, 42);
mesh.rotation = new THREE.Vector3(0.5 * Math.PI, 0, 0);
mesh.scale = new THREE.Vector3(1.2, 0, 0);
// THREE.Camera
let camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
camera.lookAt(new THREE.Vector(x, y, z));
// THREE.JS LIGHT SOURCES
let ambientLight = new THREE.AmbientLight( // does not case shadows
new THREE.Color('#0c0c0c'));
scene.add(ambientLight);
let pointLight = new THREE.PointLight(
new THREE.Color('#ccffcc'));
pointLight.distance = 100;
pointLigth.intensity = 1;
pointLight.position.set(0, 1, 3);
scene.add(pointLight);
// THREE.JS MATERIALS
LineBasicMaterial
LineDashedMaterial
new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
new THREE.MeshNormalMaterial({ side: THREE.DoubleSide });
let meshes = THREE.SceneUtils.createMultiMaterialObject(
geometry, [meshMaterial, wireframeMaterial]
);
// THREE.JS GEOMETRIES
// 2D
const geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(-10, 0, 0));
geometry.vertices.push(new THREE.Vector3(0, 10, 0));
geometry.vertices.push(new THREE.Vector3(10, 0, 0));
const line = new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: 0xff0000 }));
const plane = new THREE.PlaneGeometry(width, height, widthSegments, heightSegments);
const circle = new THREE.CircleGeometry(radius, segments, thetaStart, thetaLength);
function drawShape() {
const shape = new THREE.Shape();
shape.moveTo(x, y);
shape.lineTo(x, y);
shape.quadraticCurveTo(aCPx, aCPy, x, y);
shape.bezierCurveTo(aCPx1, aCPy1, aCPx2, aCPy2, x, y);
shape.splineThru([
new THREE.Vector2(32, 30),
new THREE.Vector2(28, 20),
new THREE.Vector2(30, 10)
]);
shape.arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise);
shape.absArc(aX, aY, aRadius, sStartAngle, aEndAngle, aClockwise);
shape.ellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise);
shape.absellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise);
return shape;
}
const shapeGeometry = new THREE.ShapeGeometry(drawShape());
// 3D
const cube = new THREE.CubeGeometry(widthX, heightY, depthZ,
widthSegments = 1, heightSegments = 1,
depthSegments = 1);
const sphere = new THREE.SphereGeometry(radius = 5,
widthSegment = 8, heightSegments = 6,
phiStart = 0, phiLength = 2 * Math.PI,
thetaStart = 0, thetaLength = Math.PI);
const cylinder = new THREE.CylinderGeometry(radiusTop = 20, radiusBottom = 20,
height = 100, segmentsX = 8,
segmentsY = 1, openEnded = false);
const torus = new THREE.TorusGeometry(radius = 100, tube = 40, radialSegments = 8,
tubularSegments = 6, arc = 2 * Math.PI);
const torusKnot = new THREE.TorusKnotGeometry(radius = 100, tube = 40,
radialSegments = 64,
tubularSegments = 8,
p = 2, q = 3, heightScale = 1);
const polyhedron = new THREE.PolyhedronGeometry(vertices, faces, radius = 1,
details = 1);
const octahedron = new THREE.OctahedronGeometry();
const tetrahedron = new THREE.TetrahedronGeometry();
const convex = new THREE.ConvexGeometry();
const lathe = new THREE.LatheGeometry();
const extrude = new THREE.ExtrudeGeometry();
const tube = new THREE.TubeGeometry();
const parametric = new THREE.ParametricGeometry();
const text = new THREE.TextGeometry();
// Convert a ttf font into typeface.js
// gero3.github.io/facetype.js/ c:\windows\fonts
// self._typeface_js = { faces: THREE.FontUtils.faces, loadFace: THREE.FontUtils.loadFace };
// <script src="js/arialRegular.facetype.js"></script>
let geometry = new THREE.TextGeometry('Foo', {
font: 'arial',
weight: 'normal',
style: 'normal',
size: 25,
height: 5,
curveSegments: 3
});
// LOADING GEOMETERIES FROM EXTERNAL RESOURCES
// JSON
// <script src="GeometryExporter.js"></script>
function saveGeometryLocally(key, geometry) {
const exporter = new THREE.GeometryExporter();
const parsedGeometry = exporter.parse(geometry);
localStorage.setItem(key, JSON.stringify(parsedGeometry));
}
function loadGeometryBack(key) {
const result = localStorage.getItem(key);
if (!result) { return null; }
const geomJson = JSON.parse(result);
const loader = new THREE.JSONLoader();
return loader.parse(geomJson);
}
// <script src="SceneExporter.js"></script>
function saveSceneLocally(key, scene) {
const exporter = new THREE.SceneExporter();
const parsedGeometry = exporter.parse(scene);
const sceneJson = JSON.stringify(parsedGeometry);
localStorage.setItem(key, sceneJson);
}
function localSceneBack(key) {
const sceneJson = localStorage.getItem(key);
if (!sceneJson) { return null; }
const loader = new THREE.SceneLoader();
sceneLoader.parse(JSON.parse(sceneJson), function (e) {
scene = e.scene;
}, '.'); // '.' defines the relative URL for other assets such as images
}
LocationCurve lc = wall.Location as LocationCurve;
Transform curveTransform = lc.Curve.ComputeDerivatives(0.5, true);
XYZ origin = curveTransform.Origin;
XYZ viewDirection = curveTransform.BasisX.Normalize();
XYZ normal = viewDirection.CrossProduct(XYZ.BasisZ).Normalize();
BoundingBoxXYZ sectionBox = new BoundingBox();
sectionBox.Transform = transform;
sectionBox.Min = new XYZ(-10, 0, 0);
sectionBox.Max = new XYZ(10, 12, 5);
/**
Object <= APIObject <= GeometryObject
<= Curve
<= Arc
<= CylindricalHelix
<= Ellipse
<= HermiteSpline
<= Line
<= NurbSpline
<= Edge
<= Face
<= ConicalFace
<= CylindricalFace
<= HermiteFace
<= PlanarFace
<= RevolvedFace
<= RuledFace
IEnumerable<GeometryObject> <= GeometryElement
<= GeometryInstance (Nested GeometryObjects and GeometryInstances)
<= Mesh
<= Point
<= PolyLine
<= Profile
<= Solid
**/
DB.Options options = new Options();
// To create transient geometry objects
GeometryCreationUtilities // no transaction is necessary
BooleanOperationUtils
HostObjectUtils
BRepBuilder
TessellatedShapeBuilder
// Revit has a left-handed, Z-up coordinate system.
// TRANSFORMATION OF ELEMENTS
// Transform represents a transformation of the affine three-space.
// Positive angles rotate anticlockwise
Transform.BasisX // => a tangent vector
Transform.BasisY // => a normal vector
Transform.BasisZ // => a binormal vector
Transform transform = Transform.Identity;
transform.Origin = origin;
transform.BasisX = normal;
transform.BasisY = XYZ.BasisZ;
transform.BasisZ = normal.CrossProduct(XYZ.Basis).Normalize();
var transformedSolid = SolidUtils.CreateTransformed(solid, transform);
ElementTransformUtils.CopyElement(); // from links to the active doc
ElementTransformUtils.MoveElement()
ElementTransformUtils.RotateElement()
ElementTransformUtils.MirrorElement()
ElementTransformUtils.GetTransformFromViewToView(srcView, dstView);
// ElementIntersectsSolidFilter
// Typically transformations are right-handed, but mirror operations
// will produce left-handed coordinate systems. Furthermore, Revit
// can produce left-handed coordinate systems via flip operations
// on certain elements.
FamilyInstance inst = GetFamliyInstnace();
XYZ orientation = inst.FacingOrientation;
// The head-to-tail method is a graphical way to add vectors
// XYZ point;
// XYZ u = XYZ.BasisZ;
// double dist = 400;
// XYZ translatedPoint = point * dist + u;
using Trace = System.Diagnostics.Trace;
[Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
class ClassName : Autodesk.Revit.UI.IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) {
// Add an EventLogTraceListener object
System.Diagnostics.Trace.Listeners.Add(
new System.Diagnostics.EventLogTraceListener("Application"));
// Lay the hands on the active document
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;
// Set up a timer
Timing myTimer = new Timing();
myTimer.StartTime();
try {
return Result.Succeeded;
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException) {
return Result.Cancelled;
}
catch (Exception ex) {
TaskDialog.Show("Exception",
string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
System.Diagnostics.Trace.Write(string.Format("{0}\n{1}",
ex.Message, ex.StackTrace));
return Result.Failed;
}
finally {
myTimer.StopTime();
System.Diagnostics.Trace
.Write(string.Format("Time elapsed: {0}s",
myTimer.Duration.TotalSeconds));
}
}
}
#define DEBUG
static EventLog log=new EventLog
{
Log="Application",
Source="Application"
};
EventLogTraceListener eventLogTraceListener=
new EventLogTraceListener(log);
TraceSwitch generalSwitch=
new TraceSwitch("General", "Entire macro");
generalSwitch.Level=TraceLevel.Verbose;
// Get the hold of the active document
Document doc=this.ActiveUIDocument.Document;
Selection sel=this.ActiveUIDocument.Selection;
// Add the EventLogTraceListener
Trace.Listeners.Add(eventLogTraceListener);
try
{
Trace.WriteLineIf(generalSwitch.TraceVerbose, "Hello, World!");
}
catch(Autodesk.Revit.Exceptions.OperationCanceledException)
{
}
catch(Exception ex)
{
Trace.WriteLineIf(generalSwitch.TraceError,string.Format("StackTrace:\n{0}\nMessage:\n{1}",
ex.StackTrace, ex.Message));
TaskDialog.Show("Exception",string.Format("StackTrace:\n{0}\nMessage:\n{1}",
ex.StackTrace, ex.Message));
}
finally
{
Trace.Flush();
Trace.Close();
}
WORKSETS
Z-LINKED-AIM-B1
Z-LINKED-SIM-B3
Z-LINKED-BSIM-ECHV
Z-LINKED-BSIM-ECLV
Workset1
Shared Levels and Grids
WALLS
F1-F2-<F3>-[<F4>]-[<F5>]-[<F6>]
F1:
E - Exterior
I - Interior
F2:
Fire resistance classes
F3 - Fn:
<RC200> - Reinforced Concrete 200 mm
Examples:
I(E)-REI60-<RC200>
BROWSER ORGANISATION
C-[COORDINATION]
D-[DOCUMENTATION]
W-[WORKING]
P-[PRESENTATION]
Z-[MISCELLANEOUS]
// Parameters
VW_FOLDER
VW_SUBFOLDER
VIEW NAMING
F1-F2-F3-F4
e.g.
D-XX-L01(0.000)-FL01
W-XX-B01(-3.000)-FL03
W-(01-08)-XX-SEC01
W-(А-Г)-XX-ELEV04
Field 1 (Subcategory):
C-[COORDINATION]
D-[DOCUMENTATION]
P-[PRESENTATION]
W-[WORKING]
Field 2 (Zone/Area):
LG1 - Basement under Buildings 1A and 1B
LG2 - Basement under building 2
LG3 - Basement under building 3
B1 - Building 1
B2 - Building 2
B3 - Building 3
TH - Townhouse
Field 3 (Level):
B02(-6.000) - Basement Level 2 at -6.000
B01(-3.300) - Basement Level 1 at -3.300
GL(-0.500) - Ground Level at -0.500
P01(1.000) - Podium Level 1 at +1.000
P02(3.000) - Podium Level 2 at +3.000
L01(0.000) - Level 1 at 0.000
L02(3.000) - Level 2 at +3.000
M02(5.000) - Mezzanine above level 1 at +5.000
Field 4(Comments)
Reserved for comments
User Addins:
%appdata%\Autodesk\Revit\Addins\20XX
Machine Addins (for all users of the machine):
C:\ProgramData\Autodesk\Revit\Addins\20XX
Addins packaged for the Autodesk Exchange store:
C:\ProgramData\Autodesk\ApplicationPlugins\
Autodesk servers and services:
C:\Program Files\Autodesk\Revit 20XX\AddIns\
Revit journals
C:\Users\username\AppData\Local\Autodesk\Revit\Autodesk Revit 20XX\Journals
Omniclass Taxonomy
C:\Users\username\AppData\Roaming\Autodesk\Revit\Autodesk Revit 20XX\OmniClassTaxonomy.txt
Uniformat Classification
C:\ProgramData\Autodesk\RVT 2020\Libraries\US Metric\UniformatClassifications.txt
WHAT IS REVIT?
REVIT ELEMENT CLASSIFICATIONS/REVIT ELEMENT HIERARCHY
ELEMENT PROPERTIES
SCHEDULING AND AREA PLANS
FAMILY EDITOR
CLASSIFICATION SYSTEMS IN REVIT
ANNOTATING DESIGN
GROUPS
DESIGN OPTIONS
PHASING
WHAT IS REVIT?
Revit, which stands for 'Revise it', is a BIM application for authoring parametric 3D models that generate geometry with embedded information for the design and construction of buildings and infastructure. It is from these intelligent models that plans, elevations, sections, perspectives details, and schedules - all of the necessary instruments to document the design of a building - can be derived. Drawings created using Revit are live views extracted from virtual building models. These models are a compilation of intelligent components that contain not only geometric attributes but also data informing decisions about the building at every stage of the process, including occupancy.
Elements in Revit are managed and manipulated through a series of parameters. These elements have bidirectional associativity, allowing the user to change the 2D views to change the 3D model. If a door is moved in a plan, that door is moved in all other views. When contrasted with traditional CAD tools, Revit gives the opportunity to more easily input, manage and export project data for project coordination and execution.
ELEMENT PROPERTIES
using the properties palette
type and instance parameters
Type parameters control information about every element of the same type. For instance, ...
Instance parameters control only the instances that are selected.
PARAMETERS
builtin
project
family
shared
global
CLASSIFICATION SYSTEMS IN REVIT
Omniclass (only families)
Masterclass (keynotes)
Uniformat (assembly code)
HANDY PHRASES
revit for energy simulations
the heating, ventilation, and air-conditioning (HVAC) system
solar heat gain
the number of occupants and their activity levels
sunshading devices
daylight dimming
lighting levels
Understand a BIM workflow and leverage BIM processes.
I see here a dead end.
Next up, let us look at how to apply Revit tools to ...
It helps to understand ...
Generate sth on the fly
working in the construction phase
establish the settings
as you can see, the central concept used by ... is
in general; as a rule; basically; in essence;
to associate x with y
the association between x and y
x represents y
to retrieve data
to pull out quantitative data
to collaborate with other designers
a federated model (architectural, strcutural, mechanical, plumbing, electrical)
a host/linked model
to run a interference check in revit
the revit interference checking process
to wrap up
data is organized in tables
// Revit.TestRunner
// Revit.TestRunner/Main.cs
// Main.cs => class Main : IExternalApplication
public Result OnStartUp(UIControlledApplication uicapp) {
_controller = new RunnerController();
_controller.Start(uicapp);
return Result.Succeeded;
}
// RunnerController
void Start(UIControlledApplication uicapp) {
_server = new FileServer(FileNames.WatchDirectory);
_server.RegisterRoute<NoParameterDto, HomeDto>(String.Empty, ProcessHome, true);
_server.StartConcurrentRoutes();
uicapp.OnIdle = (sender, e) => {
UIApplication uiapp = sender as UIApplication;
_server.ProceedNextNotConcurrent();
};
}
// Revit.TestRunner.Shared/Communication/FileNames.cs
String WatchDirectory = Path.Combine(Environment.GetFolderPath(
Environment.GetSpecialFolder.ApplicationData), "Revit.TestRunner"); // $env:AppData\Revit.TestRunner
// Revit.TestRunner.Shared/Communication/Server/FileServer.cs
// Revit.TestRunner.Shared/Dto/BaseRequestDto.cs
public enum DtoType {
NoParameterDto, HomeDto, ExploreRequestDto,
ExploreResponseDto, TestRequestDto, TestResponseDto, Unknow
}
class BaseRequestDto {
public DtoType DtoType { get; }
public String RequestId { get; set; }
public DateTime Timestamp { get; set; }
public String ClientName { get; set; }
public String ClientVersion { get; set }
}
class NoParameterDto : BaseRequestDto {}
class ExploreRequestDto : BaseRequestDto {
public String AssemblyPath { get; set; }
}
class HomeDto : BaseRequestDto {
public String LogFilePath { get; set; }
public String RevitVersion { get; set; }
public String ExplorePath { get; set; }
public String TestPath { get; set; }
}
class BaseResponseDto {
public DtoType DtoType { get; }
public String RequestId { get; set; }
public DateTime Timestamp { get; set; }
public String ThisPath { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment