应用程序:ObjectViewer
Revit平台:所有
Revit版本:2011.0
首次发布于:9.0
编程语言:C#
技能等级:高级
类别:视图
类型:ExternalCommand
主题:显示元素的几何形状,获取和设置其参数值。
概要:
这个例子演示了两个主要的特点:
1.如何获取所选元素的物理或分析模型。
2.如何获取和设置所选元素的参数值。
类:
Autodesk.Revit.UI.IExternalCommand
Autodesk.Revit.DB.Element
Autodesk.Revit.DB.GeometryElement
Autodesk.Revit.DB.Parameter
Autodesk.Revit.DB.GeometryObject
Autodesk.Revit.DB.Transform
Autodesk.Revit.DB.Structure.AnalyticalModel
项目文件:
Command.cs
该文件包含“Command”类,该类继承自“IExternalCommand”接口并实现“Execute”方法。
ErrorMessageException.cs
它包含一个名为“ErrorMessageException”的类,用于通过IExternalCommand中的Execute方法将错误消息传递到UI或内部错误消息框。
GeometryData.cs
它包含一个名为“GeometryData”的类,该类用于获取Revit几何数据并将数据转换为适当的GDI格式。
Graphics2DData.cs
它包含:
一个名为“Graphics2DData”的类,它是用于图形2D的数据类
一个从“Graphics2DData”继承并表示具有未初始化成员数据的PointF类的名为“EmptyGraphics2DData”的类。
Graphics3DData.cs
它包含一个名为“Graphics3DData”的类,该类是用于图形3D的数据类。
MathUtil.cs
它包含一个名为“MathUtil”的类,该类提供矩阵算法。
ModelData.cs
它包含一个名为“ModelData”的类,该类用于从元素的分析模型生成GraphicsData。
ObjectViewer.cs
它包含“ObjectViewer”类,该类是ObjectViewer应用程序的主要命令类。
ObjectViewerForm.cs
它包含“ObjectViewerForm”类,该类用于在PictureBox中显示所选元素,在DataGridView中显示其参数;还允许通过RadioButton、ComboBox等在不同条件下显示元素。
Para.cs
它包含一个名为“Para”的类,该类用于定义元素的参数。
ParasFactory.cs
它包含一个名为“ParasFactory”的类,该类用于创建一个“SortableBindingList<Para>”集合。 SortableBindingList可以根据Element存储有关参数的信息。
Sketch.cs
它包含一个名为“Sketch3D”的类,该类提供在PictureBox中绘制对象的方法并处理操作“Move”“Zoom”“Rotate”。
UCS.cs
它包含一个名为“UCS”的类,它代表用户坐标系。
Vector.cs
它包含一个名为“Vector”的类,该类是用于存储点坐标值的Point类。
说明:
本示例演示以下功能:
- 命令仅适用于选择的一个元素。
- 在对话框中,在左侧显示选择的元素的预览窗口,右侧显示通用属性网格。
- 对话框包含用于在物理模型和分析模型之间切换的单选按钮。如果元素没有物理或分析模型,则选项应禁用,并且预览窗口应为灰色。
- 对话框包含用于选择以下意见的列表:
- 物理模型的详细级别。
- 物理模型的视图。
- 用于两个模型(物理模型和分析模型)的视图方向。
- 所选元素的几何形状、物理或分析显示在预览窗格中。元素的通用属性应在网格中显示。
- 预览面板默认为视图方向为-1,-1,-1,即从一个角度向下看对象。
- 当鼠标位于预览窗口的区域内时,用户可以缩放、旋转和移动模型:
- 单击键‘A’,‘S’,‘D’,‘W’可将模型向左、向下、向右、向上移动。
- 单击‘上箭头’、‘下箭头’、‘左箭头’、‘右箭头’、‘Pg Up’、‘Pg Down’可将模型围绕中心旋转。
- 单击‘Home’和‘End’键可放大和缩小模型。
- 网格中显示的所有参数及其名称、值、单位名称。如果输入值可接受且此参数不是只读的,则可以成功更改参数的值。
实现:
- 物理模型可通过元素的Geometry属性获得。
- 分析模型可以在特定元素上可用的AnalyticalModel属性中找到。有几种形式的分析模型都应显示在本示例中。
- 特别注意Inplace Family Instances,以确保它们正确显示。
说明:
1. 绘制一条线、墙、梁或桌子等。
2. 选择其中一个元素,并运行此命令。
3. 将显示一个对话框,其中模式将被呈现在PictureBox中,并在DataGridView中显示其参数,允许通过更改DataGridView中的值来更改参数的值。
4. 选择单选按钮“物理模型”或“分析模型”,以在所选元素的物理模型和分析模型之间切换。
注:如果作为元素没有某些模型,则PictureBox应变为灰色。
5. 如上所述,单击一些键可以移动、旋转或缩放模型,可以从不同的角度看到模型。
6. 改变“详细级别”、“视图方向”下拉框和“显示视图”列表框中的选择将导致PictureBox的转换。它类似于Revit中的操作。
源代码
完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码
ErrorMessageException.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// pass error message to UI or back to internal error messagebox by Execute method in IExternalCommand
/// </summary>
public class ErrorMessageException : ApplicationException
{
/// <summary>
/// constructor entirely using baseclass'
/// </summary>
public ErrorMessageException()
: base()
{
}
/// <summary>
/// constructor entirely using baseclass'
/// </summary>
/// <param name="message">error message</param>
public ErrorMessageException(String message)
: base(message)
{
}
}
}
GeometryData.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Element = Autodesk.Revit.DB.Element;
using GeometryElement = Autodesk.Revit.DB.GeometryElement;
using GeometryOptions = Autodesk.Revit.DB.Options;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// The GeometryDatafactory object is used to transform Revit geometry data
/// to appropriate format for GDI.
/// </summary>
public class GeometryData
{
// boundingBox of the geometry
private BoundingBoxXYZ m_bbox;
// curves can represent the wireframe of the geometry
private List<List<XYZ>> m_curve3Ds = new List<List<XYZ>>();
/// <summary>
/// 3D graphics data of the geometry
/// </summary>
public Graphics3DData Data3D
{
get
{
return new Graphics3DData(new List<List<XYZ>>(m_curve3Ds), m_bbox);
}
}
/// <summary>
/// create 3D and 2D data of given GeometryElement
/// </summary>
/// <param name="elem"></param>
/// <param name="detail"></param>
/// <param name="currentView"></param>
public GeometryData(Element elem, ViewDetailLevel detail, View currentView)
{
Options opt = Command.CommandData.Application.Application.Create.NewGeometryOptions();
opt.DetailLevel = detail;
opt.ComputeReferences = false;
GeometryElement geoElement = elem.get_Geometry(opt);
Autodesk.Revit.DB.XYZ xyz = new Autodesk.Revit.DB.XYZ(0, 0, 0);
Transform transform = Transform.CreateTranslation(xyz);
AddGeoElement(geoElement, transform);
m_bbox = elem.get_BoundingBox(currentView);
}
/// <summary>
/// create 3D and 2D data of given GeometryElement
/// </summary>
/// <param name="elem">of which geometry data be gotten</param>
/// <param name="currentView">current view of Revit</param>
public GeometryData(Element elem, View currentView)
{
Options opt = Command.CommandData.Application.Application.Create.NewGeometryOptions();
opt.View = currentView;
opt.ComputeReferences = false;
GeometryElement geoElement = elem.get_Geometry(opt);
Autodesk.Revit.DB.XYZ xyz = new Autodesk.Revit.DB.XYZ(0, 0, 0);
Transform transform = Transform.CreateTranslation(xyz);
AddGeoElement(geoElement, transform);
m_bbox = elem.get_BoundingBox(currentView);
}
/// <summary>
/// get the solids in a Geometric primitive
/// </summary>
/// <param name="obj">a geometry object of element</param>
/// <param name="transform"></param>
private void AddGeoElement(GeometryObject obj, Transform transform)
{
GeometryElement geometry = obj as GeometryElement;
if (null == geometry)
{
return;
}
//get all geometric primitives contained in the GeometryElement
IEnumerator<GeometryObject> Objects = geometry.GetEnumerator();
AddGeometryObjects(Objects, transform);
}
/// <summary>
/// iterate GeometryObject in GeometryObjectArray and generate data accordingly
/// </summary>
/// <param name="objects"></param>
/// <param name="transform"></param>
private void AddGeometryObjects(IEnumerator<GeometryObject> objects, Transform transform)
{
//foreach (GeometryObject o in objects)
while (objects.MoveNext())
{
GeometryObject o = objects.Current;
//if the type of the geometric primitive is Solid
string geoType = o.GetType().Name;
switch (geoType)
{
case "Solid":
AddSolid(o, transform);
break;
case "Face":
AddFace(o, transform);
break;
case "Mesh":
AddMesh(o, transform);
break;
case "Curve":
case "Line":
case "Arc":
AddCurve(o, transform);
break;
case "Profile":
AddProfile(o, transform);
break;
case "Element":
AddGeoElement(o, transform);
break;
case "Instance":
AddInstance(o, transform);
break;
case "Edge":
AddEdge(o, transform);
break;
default:
break;
}
}
}
/// <summary>
/// generate data of a Solid
/// </summary>
/// <param name="obj"></param>
/// <param name="transform"></param>
private void AddSolid(GeometryObject obj, Transform transform)
{
Solid solid = obj as Solid;
if (null == solid)
{
return;
}
//a solid has many faces
FaceArray faces = solid.Faces;
if (faces.Size == 0)
{
return;
}
foreach (Face face in faces)
{
AddFace(face, transform);
}
}
/// <summary>
/// generate data of a Face
/// </summary>
/// <param name="obj"></param>
/// <param name="transform"></param>
private void AddFace(GeometryObject obj, Transform transform)
{
Face face = obj as Face;
if (null == face)
{
return;
}
Mesh mesh = face.Triangulate();
if (null == mesh)
{
return;
}
AddMesh(mesh, transform);
}
/// <summary>
/// generate data of a Profile
/// </summary>
/// <param name="obj"></param>
/// <param name="transform"></param>
private void AddProfile(GeometryObject obj, Transform transform)
{
Profile profile = obj as Profile;
if (null == profile)
{
return;
}
foreach (Curve curve in profile.Curves)
{
AddCurve(curve, transform);
}
}
/// <summary>
/// generate data of a Mesh
/// </summary>
/// <param name="obj"></param>
/// <param name="transform"></param>
private void AddMesh(GeometryObject obj, Transform transform)
{
Mesh mesh = obj as Mesh;
if (null == mesh)
{
return;
}
//a face has a mesh, all meshes are made of triangles
for (int i = 0; i < mesh.NumTriangles; i++)
{
MeshTriangle triangular = mesh.get_Triangle(i);
List<XYZ> points = new List<XYZ>();
try
{
for (int n = 0; n < 3; n++)
{
Autodesk.Revit.DB.XYZ point = triangular.get_Vertex(n);
Autodesk.Revit.DB.XYZ newPoint = MathUtil.GetBasis(point, transform);
points.Add(newPoint);
}
Autodesk.Revit.DB.XYZ iniPoint = points[0];
points.Add(iniPoint);
m_curve3Ds.Add(points);
}
catch
{
}
}
}
/// <summary>
/// generate data of a Curve
/// </summary>
/// <param name="obj"></param>
/// <param name="transform"></param>
private void AddCurve(GeometryObject obj, Transform transform)
{
Curve curve = obj as Curve;
if (null == curve)
{
return;
}
if (curve.IsBound)
{
List<XYZ> points = curve.Tessellate() as List<XYZ>;
List<XYZ> result = new List<XYZ>();
foreach (Autodesk.Revit.DB.XYZ point in points)
{
Autodesk.Revit.DB.XYZ newPoint = MathUtil.GetBasis(point, transform);
result.Add(newPoint);
}
m_curve3Ds.Add(result);
}
}
/// <summary>
/// generate data of a Instance
/// </summary>
/// <param name="obj"></param>
/// <param name="transform"></param>
private void AddInstance(GeometryObject obj, Transform transform)
{
GeometryInstance instance = obj as GeometryInstance;
if (null == instance)
{
return;
}
//get a transformation of the affine 3-space
Transform allTransform = AddTransform(transform, instance.Transform);
GeometryElement instanceGeometry = instance.SymbolGeometry;
if (null == instanceGeometry)
{
return;
}
//get all geometric primitives contained in the GeometryElement
//GeometryObjectArray instanceGeometries = instanceGeometry.Objects;
IEnumerator<GeometryObject> Objects = instanceGeometry.GetEnumerator();
AddGeometryObjects(Objects, allTransform);
}
/// <summary>
/// generate data of a Edge
/// </summary>
/// <param name="obj"></param>
/// <param name="transform"></param>
private void AddEdge(GeometryObject obj, Transform transform)
{
Edge edge = obj as Edge;
if (null == edge)
{
return;
}
List<XYZ> points = edge.Tessellate() as List<XYZ>;
List<XYZ> result = new List<XYZ>();
foreach (Autodesk.Revit.DB.XYZ point in points)
{
Autodesk.Revit.DB.XYZ newPoint = MathUtil.GetBasis(point, transform);
result.Add(newPoint);
}
m_curve3Ds.Add(result);
}
/// <summary>
/// Add 2 Transform Matrix
/// </summary>
/// <param name="tran1"></param>
/// <param name="tran2"></param>
/// <returns></returns>
private Transform AddTransform(Transform tran1, Transform tran2)
{
Autodesk.Revit.DB.XYZ xyz = new Autodesk.Revit.DB.XYZ(0, 0, 0);
Transform result = Transform.CreateTranslation(xyz);
result.Origin = MathUtil.AddXYZ(tran1.Origin, tran2.Origin);
Autodesk.Revit.DB.XYZ[] left = new Autodesk.Revit.DB.XYZ[3];
Autodesk.Revit.DB.XYZ[] right = new Autodesk.Revit.DB.XYZ[3];
for (int i = 0; i < 3; i++)
{
left[i] = tran1.get_Basis(i);
right[i] = tran2.get_Basis(i);
}
Autodesk.Revit.DB.XYZ[] temp = MathUtil.MultiCross(left, right);
for (int i = 0; i < 3; i++)
{
result.set_Basis(i, temp[i]);
}
return result;
}
}
}
Graphics2DData.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Collections.ObjectModel;
using Autodesk.Revit.DB;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// data class for graphics 2D
/// </summary>
public class Graphics2DData
{
// curves represent the wireframe of the 2D geometry
private readonly List<PointF[]> m_curves = new List<PointF[]>();
// the number of points consists of m_curves
private readonly int m_numPoints;
private static EmptyGraphics2DData m_empty = new EmptyGraphics2DData();
// boundingbox of the 2D geometry
private RectangleF m_bbox = new RectangleF(0.0f, 0.0f, 1.0f, 1.0f);
/// <summary>
/// Represents a new instance of the Graphics2DData class with member data left uninitialized
/// </summary>
public static Graphics2DData Empty
{
get
{
return m_empty;
}
}
/// <summary>
/// Number of points consists of 2D geometry's wireframe
/// </summary>
public int NumPoints
{
get
{
return m_numPoints;
}
}
/// <summary>
/// BoundingBox of the 2D geometry
/// </summary>
public RectangleF BBox
{
get
{
return m_bbox;
}
}
/// <summary>
/// Curves represent the wireframe of the 2D geometry
/// </summary>
public List<PointF[]> ConstCurves
{
get
{
return m_curves;
}
}
/// <summary>
/// only for Empty class
/// </summary>
protected Graphics2DData()
{
}
/// <summary>
/// constructor
/// </summary>
/// <param name="curves">curves represent the wireframe of the 2D geometry</param>
public Graphics2DData(List<List<UV>> curves)
{
// initialize m_curves and m_bbox
bool isFirst = true; // is the first List<UV> instance in curves
foreach (List<UV> uvs in curves)
{
PointF[] pnts = new PointF[uvs.Count];
m_curves.Add(pnts);
for (int i = 0; i < uvs.Count; i++)
{
Autodesk.Revit.DB.UV uv = uvs[i];
pnts[i] = new PointF((float)uv.U, (float)uv.V);
RectangleF tmpBBox = new RectangleF(pnts[i], new SizeF(0.0f, 0.0f));
m_numPoints++;
if (!isFirst)
{
// union the m_bbox with next curve's BBox
m_bbox = RectangleF.Union(m_bbox, tmpBBox);
}
else
{
m_bbox = tmpBBox;
isFirst = false;
}
}
}
}
/// <summary>
/// Represents a PointF class with member data left uninitialized
/// </summary>
class EmptyGraphics2DData : Graphics2DData
{
}
}
}
Graphics3DData.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections.ObjectModel;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.DB;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// trigger when view data updated
/// </summary>
public delegate void UpdateViewDelegate();
/// <summary>
/// data class for graphics 3D
/// </summary>
public class Graphics3DData
{
/// <summary>
/// Chooses the camera direction to the view
/// </summary>
public enum ViewDirections
{
/// <summary>
/// top direction
/// </summary>
Top,
/// <summary>
/// front view
/// </summary>
Front,
/// <summary>
/// left view
/// </summary>
Left,
/// <summary>
/// right view
/// </summary>
Right,
/// <summary>
/// bottom view
/// </summary>
Bottom,
/// <summary>
/// back view
/// </summary>
Back,
/// <summary>
/// iso view diection
/// </summary>
IsoMetric
}
// default angle when rotate around X,Y,Z axis
private const double RotateAngle = System.Math.PI / 90;
// initial curves data before UCS transform
private readonly List<List<Vector>> m_iniCurves = new List<List<Vector>>();
// curves data after UCS transform
private readonly List<List<Vector>> m_curves = new List<List<Vector>>();
// number of points representing the 3D geometry
private readonly int m_numPoints;
// BoundingBox of the 3D geometry
private BoundingBoxXYZ m_bbox = new BoundingBoxXYZ();
// current UCS
private UCS m_currentUCS = new UCS();
/// <summary>
/// Current UCS used to transform
/// </summary>
public UCS CurrentUCS
{
get
{
return m_currentUCS;
}
set
{
m_currentUCS = value;
UpdateDisplayData(m_currentUCS);
if (null != UpdateViewEvent)
{
UpdateViewEvent();
}
}
}
/// <summary>
/// Number of points representing the 3D geometry
/// </summary>
public int NumPoints
{
get
{
return m_numPoints;
}
}
// 7 UCS according to camera directions in ViewDirections
private static readonly UCS[] SpecialUCSs = new UCS[7];
// small angle used to Rotate UCS around X, Y, Z axis
private static readonly UCS RotateXUCS;
private static readonly UCS RotateAntiXUCS;
private static readonly UCS RotateYUCS;
private static readonly UCS RotateAntiYUCS;
private static readonly UCS RotateZUCS;
private static readonly UCS RotateAntiZUCS;
/// <summary>
/// static constructor used to initialize static members
/// </summary>
static Graphics3DData()
{
// initialize small angle
double angle = RotateAngle;
double antiAngle = -RotateAngle;
double sin = Math.Sin(angle);
double cos = Math.Cos(angle);
double antiSin = Math.Sin(antiAngle);
double antiCos = Math.Cos(antiAngle);
// initialize 6 Rotate UCS
Vector origin = new Vector();
RotateXUCS =
new UCS(origin, new Vector(1.0, 0.0, 0.0), new Vector(0.0, cos, sin));
RotateAntiXUCS =
new UCS(origin, new Vector(1.0, 0.0, 0.0), new Vector(0.0, antiCos, antiSin));
RotateYUCS =
new UCS(origin, new Vector(cos, 0.0, -sin), new Vector(0.0, 1.0, 0.0));
RotateAntiYUCS =
new UCS(origin, new Vector(antiCos, 0.0, -antiSin), new Vector(0.0, 1.0, 0.0));
RotateZUCS =
new UCS(origin, new Vector(cos, sin, 0.0), new Vector(-sin, cos, 0.0));
RotateAntiZUCS =
new UCS(origin, new Vector(antiCos, antiSin, 0.0), new Vector(-antiSin, antiCos, 0.0));
// initialize 7 special UCS
SpecialUCSs[(int)ViewDirections.IsoMetric] = new UCS(origin,
new Vector(-0.408248290463863, 0.408248290463863, 0.816496580927726),
new Vector(0.707106781186548, 0.707106781186548, 0.0));
SpecialUCSs[(int)ViewDirections.Top] =
new UCS(origin, new Vector(1.0, 0.0, 0.0), new Vector(0.0, 1.0, 0.0));
SpecialUCSs[(int)ViewDirections.Front] =
new UCS(origin, new Vector(-1.0, 0.0, 0.0), new Vector(0.0, 0.0, 1.0));
SpecialUCSs[(int)ViewDirections.Left] =
new UCS(origin, new Vector(0.0, -1.0, 0.0), new Vector(0.0, 0.0, 1.0));
SpecialUCSs[(int)ViewDirections.Right] =
new UCS(origin, new Vector(0.0, 1.0, 0.0), new Vector(0.0, 0.0, 1.0));
SpecialUCSs[(int)ViewDirections.Bottom] =
new UCS(origin, new Vector(-1.0, 0.0, 0.0), new Vector(0.0, 1.0, 0.0));
SpecialUCSs[(int)ViewDirections.Back] =
new UCS(origin, new Vector(1.0, 0.0, 0.0), new Vector(0.0, 0.0, 1.0));
}
/// <summary>
/// view data update
/// </summary>
public event UpdateViewDelegate UpdateViewEvent;
/// <summary>
/// Curves represent the wireframe of the 3D geometry
/// </summary>
public List<List<Vector>> ConstCurves
{
get
{
return m_curves;
}
}
/// <summary>
/// BoundingBox of the 3D geometry
/// </summary>
public BoundingBoxXYZ BBox
{
get
{
return m_bbox;
}
}
/// <summary>
/// constructor
/// </summary>
/// <param name="curves">curves represent the wireframe of the 3D geometry</param>
/// <param name="bbox">oundingBox of the 3D geometry</param>
public Graphics3DData(List<List<XYZ>> curves, BoundingBoxXYZ bbox)
{
if (null == bbox)
{
return;
}
foreach (UCS ucs in SpecialUCSs)
{
ucs.Origin = FindBBoxCenter(bbox);
}
foreach (List<XYZ> pnts in curves)
{
List<Vector> vectors = new List<Vector>();
m_iniCurves.Add(vectors);
foreach (Autodesk.Revit.DB.XYZ pnt in pnts)
{
vectors.Add(new Vector(pnt.X, pnt.Y, pnt.Z));
m_numPoints++;
}
}
SetViewDirection(ViewDirections.IsoMetric);
InitializeBBox(bbox);
}
/// <summary>
/// change the camera direction to the geometry
/// </summary>
/// <param name="viewDirection">camera direction</param>
public void SetViewDirection(ViewDirections viewDirection)
{
m_currentUCS = SpecialUCSs[(int)viewDirection];
UpdateDisplayData(m_currentUCS);
}
/// <summary>
/// rotate around Z axis with default angle
/// </summary>
/// <param name="direction">minus or positive angle</param>
public void RotateZ(bool direction)
{
if (direction)
{
m_currentUCS = m_currentUCS + RotateZUCS;
UpdateDisplayData(m_currentUCS);
}
else
{
m_currentUCS = m_currentUCS + RotateAntiZUCS;
UpdateDisplayData(m_currentUCS);
}
}
/// <summary>
/// rotate around Y axis with default angle
/// </summary>
/// <param name="direction">minus or positive angle</param>
public void RotateY(bool direction)
{
if (direction)
{
m_currentUCS = m_currentUCS + RotateYUCS;
UpdateDisplayData(m_currentUCS);
}
else
{
m_currentUCS = m_currentUCS + RotateAntiYUCS;
UpdateDisplayData(m_currentUCS);
}
}
/// <summary>
/// rotate around X axis with default angle
/// </summary>
/// <param name="direction">minus or positive angle</param>
public void RotateX(bool direction)
{
if (direction)
{
m_currentUCS = m_currentUCS + RotateXUCS;
UpdateDisplayData(m_currentUCS);
}
else
{
m_currentUCS = m_currentUCS + RotateAntiXUCS;
UpdateDisplayData(m_currentUCS);
}
}
/// <summary>
/// update data according to current UCS
/// </summary>
/// <param name="lc"></param>
private void UpdateDisplayData(UCS lc)
{
m_curves.Clear();
foreach (List<Vector> iniVectors in m_iniCurves)
{
List<Vector> vectors = new List<Vector>();
m_curves.Add(vectors);
for (int i = 0; i < iniVectors.Count; i++)
{
// transform points to local coordinate system
vectors.Add(lc.GC2LC(iniVectors[i]));
}
}
// trigger update view event
if (null != UpdateViewEvent)
{
UpdateViewEvent();
}
}
/// <summary>
/// move the BoundingBox to the center of the Coordinate System,
/// modify its size to the size of Geometry's BoundingBox
/// </summary>
/// <param name="bbox"></param>
private void InitializeBBox(BoundingBoxXYZ bbox)
{
Autodesk.Revit.DB.XYZ size = MathUtil.SubXYZ(bbox.Max, bbox.Min);
m_bbox.Max = MathUtil.DivideXYZ(size, 2.0);
m_bbox.Min = MathUtil.DivideXYZ(size, -2.0);
}
/// <summary>
/// find the center of the BoundingBox
/// </summary>
/// <param name="bbox">BoundingBox</param>
/// <returns>center Point</returns>
private Vector FindBBoxCenter(BoundingBoxXYZ bbox)
{
Autodesk.Revit.DB.XYZ center = MathUtil.DivideXYZ(MathUtil.AddXYZ(bbox.Max, bbox.Min), 2.0);
return MathUtil.XYZ2Vector(center);
}
}
}
MathUtil.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.DB;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// utility class provide arithmetic of matrix
/// </summary>
public static class MathUtil
{
/// <summary>
/// multiply cross two matrix
/// </summary>
/// <param name="m1">left matrix</param>
/// <param name="m2">right matrix</param>
/// <returns>result matrix</returns>
public static Autodesk.Revit.DB.XYZ[] MultiCross(Autodesk.Revit.DB.XYZ[] m1, Autodesk.Revit.DB.XYZ[] m2)
{
Autodesk.Revit.DB.XYZ[] result = new Autodesk.Revit.DB.XYZ[3];
for (int i = 0; i < 3; i++)
{
result[i] = new Autodesk.Revit.DB.XYZ();
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
switch (j)
{
case 0:
result[i] = new XYZ(
result[i].X + ((m1[i])[k] * (m2[k])[j]),
result[i].Y,
result[i].Z);
break;
case 1:
result[i] = new XYZ(
result[i].X,
result[i].Y + (m1[i])[k] * (m2[k])[j],
result[i].Z);
break;
case 2:
result[i] = new XYZ(
result[i].X,
result[i].Y,
result[i].Z + (m1[i])[k] * (m2[k])[j]);
break;
default:
break;
}
}
}
}
return result;
}
/// <summary>
/// subtract two Autodesk.Revit.DB.XYZ as Matrix
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
/// <returns></returns>
public static Autodesk.Revit.DB.XYZ SubXYZ(Autodesk.Revit.DB.XYZ lhs, Autodesk.Revit.DB.XYZ rhs)
{
double x = lhs.X - rhs.X;
double y = lhs.Y - rhs.Y;
double z = lhs.Z - rhs.Z;
Autodesk.Revit.DB.XYZ result = new Autodesk.Revit.DB.XYZ (x, y, z);
return result;
}
/// <summary>
/// Add two Autodesk.Revit.DB.XYZ as Matrix
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
/// <returns></returns>
public static Autodesk.Revit.DB.XYZ AddXYZ(Autodesk.Revit.DB.XYZ lhs, Autodesk.Revit.DB.XYZ rhs)
{
double x = lhs.X + rhs.X;
double y = lhs.Y + rhs.Y;
double z = lhs.Z + rhs.Z;
Autodesk.Revit.DB.XYZ result = new Autodesk.Revit.DB.XYZ (x, y, z);
return result;
}
/// <summary>
/// divide a Autodesk.Revit.DB.XYZ by a number
/// </summary>
/// <param name="lhs">divided XYZ</param>
/// <param name="rhs">number</param>
/// <returns>result</returns>
public static Autodesk.Revit.DB.XYZ DivideXYZ(Autodesk.Revit.DB.XYZ lhs, double rhs)
{
return new Autodesk.Revit.DB.XYZ (lhs.X / rhs, lhs.Y / rhs, lhs.Z / rhs);
}
/// <summary>
/// get the coordinates from old coordinate system in the new coordinate system
/// </summary>
/// <param name="point"></param>
/// <param name="transform"></param>
/// <returns></returns>
public static Autodesk.Revit.DB.XYZ GetBasis(Autodesk.Revit.DB.XYZ point, Transform transform)
{
double x = point.X;
double y = point.Y;
double z = point.Z;
double x2;
double y2;
double z2;
//transform basis of the old coordinate system in the new coordinate system
Autodesk.Revit.DB.XYZ b0 = transform.get_Basis(0);
Autodesk.Revit.DB.XYZ b1 = transform.get_Basis(1);
Autodesk.Revit.DB.XYZ b2 = transform.get_Basis(2);
Autodesk.Revit.DB.XYZ origin = transform.Origin;
//transform the origin of the old coordinate system in the new coordinate system
x2 = x * b0.X + y * b1.X + z * b2.X + origin.X;
y2 = x * b0.Y + y * b1.Y + z * b2.Y + origin.Y;
z2 = x * b0.Z + y * b1.Z + z * b2.Z + origin.Z;
Autodesk.Revit.DB.XYZ newPoint = new Autodesk.Revit.DB.XYZ (x2, y2, z2);
return newPoint;
}
/// <summary>
/// transform a Vector instance to a Autodesk.Revit.DB.XYZ instance
/// </summary>
/// <param name="v">transformed Vector</param>
/// <returns>result XYZ</returns>
public static Autodesk.Revit.DB.XYZ Vector2XYZ(Vector v)
{
return new Autodesk.Revit.DB.XYZ (v.X, v.Y, v.Z);
}
/// <summary>
/// transform a Autodesk.Revit.DB.XYZ instance to a Vector instance
/// </summary>
/// <param name="pnt">transformed XYZ</param>
/// <returns>result Vector</returns>
public static Vector XYZ2Vector(Autodesk.Revit.DB.XYZ pnt)
{
return new Vector(pnt.X, pnt.Y, pnt.Z);
}
}
}
ModelData.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections.ObjectModel;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Element = Autodesk.Revit.DB.Element;
using GeomElement = Autodesk.Revit.DB.GeometryElement;
using GeomInstance = Autodesk.Revit.DB.Instance;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// generate GraphicsData by give geometry object
/// </summary>
public class ModelData
{
// BoundingBox of the geometry
private BoundingBoxXYZ m_bbox;
private List<List<XYZ>> m_curve3Ds = new List<List<XYZ>>();
private List<List<UV>> m_curve2Ds = new List<List<UV>>();
/// <summary>
/// 3D graphics data of the geometry
/// </summary>
public Graphics3DData Data3D
{
get
{
return new Graphics3DData(new List<List<XYZ>>(m_curve3Ds), m_bbox);
}
}
/// <summary>
/// 2D graphics data of the geometry
/// </summary>
public Graphics2DData Data2D
{
get
{
return new Graphics2DData(new List<List<UV>>(m_curve2Ds));
}
}
/// <summary>
/// Generate appropriate graphics data object from exact analytical model type.
/// </summary>
/// <param name="element">The selected element maybe has analytical model lines</param>
/// <returns>A graphics data object appropriate for GDI.</returns>
public ModelData(Element element)
{
try
{
AnalyticalModel analyticalMode = GetAnalyticalModel(element);
View currentView = Command.CommandData.Application.ActiveUIDocument.Document.ActiveView;
m_bbox = element.get_BoundingBox(currentView);
if (null == analyticalMode)
{
return;
}
GetModelData(analyticalMode);
}
catch (Exception)
{
}
}
/// <summary>
/// Get the analytical model object from an element.
/// </summary>
/// <param name="element">The selected element maybe has analytical model lines</param>
/// <returns>Return analytical model object, or else return null.</returns>
private AnalyticalModel GetAnalyticalModel(Element element)
{
return element.GetAnalyticalModel();
}
/// <summary>
/// create GraphicsData of give AnalyticalModel
/// </summary>
/// <param name="model">AnalyticalModel contains geometry data</param>
/// <returns>A graphics data object appropriate for GDI.</returns>
private void GetModelData(AnalyticalModel model)
{
foreach (Curve curve in model.GetCurves(AnalyticalCurveType.RawCurves))
{
try
{
m_curve3Ds.Add(curve.Tessellate() as List<XYZ>);
}
catch
{
}
}
}
}
}
ObjectViewer.cs
//
// (C) Copyright 2003-2019 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.
//
namespace Revit.SDK.Samples.ObjectViewer.CS
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Structure;
using Element = Autodesk.Revit.DB.Element;
using GeometryElement = Autodesk.Revit.DB.GeometryElement;
/// <summary>
/// main command class of the ObjectViewer application
/// </summary>
public class ObjectViewer
{
/// <summary>
/// choose the display kinds of preview
/// </summary>
public enum DisplayKinds
{
/// <summary>
/// Geometry Model
/// </summary>
GeometryModel,
/// <summary>
/// AnalyticalModel
/// </summary>
AnalyticalModel
}
private Element m_selected; // selected element to display
private View m_currentView; // current View for preview
// current detail level for preview
private ViewDetailLevel m_detailLevel = ViewDetailLevel.Fine;
private List<View> m_allViews = new List<View>(); // all Views in current project
// current display kind for preview
private DisplayKinds m_displayKind = DisplayKinds.GeometryModel;
// selected element's parameters' data
private SortableBindingList<Para> m_paras;
// current sketch instance to draw the element
private Sketch3D m_currentSketch3D = null;
// indicate whether select view or detail
private bool m_isSelectView = true;
/// <summary>
/// Current display kind for preview
/// </summary>
public DisplayKinds DisplayKind
{
get
{
return m_displayKind;
}
set
{
m_displayKind = value;
UpdateSketch3D();
}
}
/// <summary>
/// Current View for preview
/// </summary>
public View CurrentView
{
get
{
return m_currentView;
}
set
{
m_currentView = value;
m_isSelectView = true;
UpdateSketch3D();
}
}
/// <summary>
/// All Views in current project
/// </summary>
public ReadOnlyCollection<View> AllViews
{
get
{
return new ReadOnlyCollection<View>(m_allViews);
}
}
/// <summary>
/// Current detail level for preview
/// </summary>
public ViewDetailLevel DetailLevel
{
get
{
return m_detailLevel;
}
set
{
m_detailLevel = value;
m_isSelectView = false;
UpdateSketch3D();
}
}
/// <summary>
/// Current sketch instance to draw the element
/// </summary>
public Sketch3D CurrentSketch3D
{
get
{
return m_currentSketch3D;
}
}
/// <summary>
/// Selected element's parameters' data
/// </summary>
public SortableBindingList<Para> Params
{
get
{
return m_paras;
}
}
/// <summary>
/// constructor
/// </summary>
public ObjectViewer()
{
UIDocument doc = Command.CommandData.Application.ActiveUIDocument;
ElementSet selection = new ElementSet();
foreach (ElementId elementId in doc.Selection.GetElementIds())
{
selection.Insert(doc.Document.GetElement(elementId));
}
// only one element should be selected
if (0 == selection.Size)
{
throw new ErrorMessageException("Please select an element.");
}
if (1 < selection.Size)
{
throw new ErrorMessageException("Please select only one element.");
}
// get selected element
foreach (Element e in selection)
{
m_selected = e;
}
// get current view and all views
m_currentView = doc.Document.ActiveView;
FilteredElementIterator itor = (new FilteredElementCollector(doc.Document)).OfClass(typeof(View)).GetElementIterator();
itor.Reset();
while (itor.MoveNext())
{
View view = itor.Current as View;
// Skip view templates because they're invisible in project browser, invalid for geometry elements
if (null != view && !view.IsTemplate)
{
m_allViews.Add(view);
}
}
// create a instance of Sketch3D
GeometryData geomFactory = new GeometryData(m_selected, m_currentView);
m_currentSketch3D = new Sketch3D(geomFactory.Data3D, Graphics2DData.Empty);
//get a instance of ParametersFactory and then use it to create Parameters
ParasFactory parasFactory = new ParasFactory(m_selected);
m_paras = parasFactory.CreateParas();
}
/// <summary>
/// update current Sketch3D using current UCS and settings
/// </summary>
private void UpdateSketch3D()
{
if (m_displayKind == DisplayKinds.GeometryModel)
{
GeometryData geomFactory;
if(m_isSelectView)
{
geomFactory = new GeometryData(m_selected, m_currentView);
m_detailLevel = ViewDetailLevel.Undefined;
}
else
{
geomFactory = new GeometryData(m_selected, m_detailLevel, m_currentView);
}
Graphics3DData geom3DData = geomFactory.Data3D;
Graphics3DData old3DData = m_currentSketch3D.Data3D;
geom3DData.CurrentUCS = old3DData.CurrentUCS;
m_currentSketch3D.Data3D = geom3DData;
m_currentSketch3D.Data2D = Graphics2DData.Empty;
}
else if (m_displayKind == DisplayKinds.AnalyticalModel)
{
ModelData modelFactory = new ModelData(m_selected);
Graphics3DData model3DData = modelFactory.Data3D;
Graphics2DData model2DData = modelFactory.Data2D;
Graphics3DData old3DData = m_currentSketch3D.Data3D;
model3DData.CurrentUCS = old3DData.CurrentUCS;
m_currentSketch3D.Data3D = model3DData;
m_currentSketch3D.Data2D = model2DData;
}
}
}
}
ObjectViewerForm.cs
//
// (C) Copyright 2003-2019 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.
//
namespace Revit.SDK.Samples.ObjectViewer.CS
{
partial class ObjectViewerForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.parametersDataGridView = new System.Windows.Forms.DataGridView();
this.physicalModelRadioButton = new System.Windows.Forms.RadioButton();
this.analyticalModelRadioButton = new System.Windows.Forms.RadioButton();
this.previewBox = new System.Windows.Forms.PictureBox();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.label5 = new System.Windows.Forms.Label();
this.viewDirectionComboBox = new System.Windows.Forms.ComboBox();
this.label4 = new System.Windows.Forms.Label();
this.viewListBox = new System.Windows.Forms.ListBox();
this.label1 = new System.Windows.Forms.Label();
this.detailLevelComboBox = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.okButton = new System.Windows.Forms.Button();
this.closeButton = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.parametersDataGridView)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.previewBox)).BeginInit();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// parametersDataGridView
//
this.parametersDataGridView.AllowUserToAddRows = false;
this.parametersDataGridView.AllowUserToDeleteRows = false;
this.parametersDataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Right)));
this.parametersDataGridView.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.parametersDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.parametersDataGridView.Location = new System.Drawing.Point(490, 25);
this.parametersDataGridView.Name = "parametersDataGridView";
this.parametersDataGridView.RowHeadersVisible = false;
this.parametersDataGridView.RowTemplate.Height = 24;
this.parametersDataGridView.Size = new System.Drawing.Size(404, 567);
this.parametersDataGridView.TabIndex = 10;
this.parametersDataGridView.TabStop = false;
//
// physicalModelRadioButton
//
this.physicalModelRadioButton.AutoSize = true;
this.physicalModelRadioButton.Checked = true;
this.physicalModelRadioButton.Location = new System.Drawing.Point(6, 110);
this.physicalModelRadioButton.Name = "physicalModelRadioButton";
this.physicalModelRadioButton.Size = new System.Drawing.Size(96, 17);
this.physicalModelRadioButton.TabIndex = 8;
this.physicalModelRadioButton.TabStop = true;
this.physicalModelRadioButton.Text = "Physical Model";
this.physicalModelRadioButton.UseVisualStyleBackColor = true;
this.physicalModelRadioButton.CheckedChanged += new System.EventHandler(this.physicalModelRadioButton_CheckedChanged);
//
// analyticalModelRadioButton
//
this.analyticalModelRadioButton.AutoSize = true;
this.analyticalModelRadioButton.Location = new System.Drawing.Point(6, 133);
this.analyticalModelRadioButton.Name = "analyticalModelRadioButton";
this.analyticalModelRadioButton.Size = new System.Drawing.Size(102, 17);
this.analyticalModelRadioButton.TabIndex = 9;
this.analyticalModelRadioButton.TabStop = true;
this.analyticalModelRadioButton.Text = "Analytical Model";
this.analyticalModelRadioButton.UseVisualStyleBackColor = true;
this.analyticalModelRadioButton.CheckedChanged += new System.EventHandler(this.analyticalModelRadioButton_CheckedChanged);
//
// previewBox
//
this.previewBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.previewBox.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.previewBox.Cursor = System.Windows.Forms.Cursors.Cross;
this.previewBox.Location = new System.Drawing.Point(12, 25);
this.previewBox.Name = "previewBox";
this.previewBox.Size = new System.Drawing.Size(472, 425);
this.previewBox.TabIndex = 4;
this.previewBox.TabStop = false;
this.previewBox.Paint += new System.Windows.Forms.PaintEventHandler(this.previewBox_Paint);
//
// groupBox1
//
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.groupBox1.Controls.Add(this.label5);
this.groupBox1.Controls.Add(this.viewDirectionComboBox);
this.groupBox1.Controls.Add(this.label4);
this.groupBox1.Controls.Add(this.viewListBox);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.detailLevelComboBox);
this.groupBox1.Controls.Add(this.physicalModelRadioButton);
this.groupBox1.Controls.Add(this.analyticalModelRadioButton);
this.groupBox1.Location = new System.Drawing.Point(12, 456);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(472, 160);
this.groupBox1.TabIndex = 6;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Preview";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(6, 65);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(78, 13);
this.label5.TabIndex = 11;
this.label5.Text = "View Direction:";
//
// viewDirectionComboBox
//
this.viewDirectionComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.viewDirectionComboBox.FormattingEnabled = true;
this.viewDirectionComboBox.Items.AddRange(new object[] {
"Top",
"Front",
"Left",
"Right",
"Bottom",
"Back",
"IsoMetric"});
this.viewDirectionComboBox.Location = new System.Drawing.Point(6, 82);
this.viewDirectionComboBox.Name = "viewDirectionComboBox";
this.viewDirectionComboBox.Size = new System.Drawing.Size(158, 21);
this.viewDirectionComboBox.TabIndex = 6;
this.viewDirectionComboBox.SelectedIndexChanged += new System.EventHandler(this.viewDirectionComboBox_SelectedIndexChanged);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(167, 16);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(82, 13);
this.label4.TabIndex = 9;
this.label4.Text = "Displayed View:";
//
// viewListBox
//
this.viewListBox.FormattingEnabled = true;
this.viewListBox.Location = new System.Drawing.Point(170, 33);
this.viewListBox.Name = "viewListBox";
this.viewListBox.Size = new System.Drawing.Size(296, 121);
this.viewListBox.TabIndex = 7;
this.viewListBox.SelectedIndexChanged += new System.EventHandler(this.viewListBox_SelectedIndexChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(6, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(66, 13);
this.label1.TabIndex = 7;
this.label1.Text = "Detail Level:";
//
// detailLevelComboBox
//
this.detailLevelComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.detailLevelComboBox.FormattingEnabled = true;
this.detailLevelComboBox.Items.AddRange(new object[] {
"Undefined",
"Coarse",
"Medium",
"Fine"});
this.detailLevelComboBox.Location = new System.Drawing.Point(6, 33);
this.detailLevelComboBox.Name = "detailLevelComboBox";
this.detailLevelComboBox.Size = new System.Drawing.Size(158, 21);
this.detailLevelComboBox.TabIndex = 5;
this.detailLevelComboBox.SelectedIndexChanged += new System.EventHandler(this.detailLevelComboBox_SelectedIndexChanged);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(13, 8);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(48, 13);
this.label2.TabIndex = 7;
this.label2.Text = "Preview:";
//
// label3
//
this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(491, 8);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(63, 13);
this.label3.TabIndex = 8;
this.label3.Text = "Parameters:";
//
// okButton
//
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.Location = new System.Drawing.Point(738, 598);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 11;
this.okButton.Text = "&OK";
this.okButton.UseVisualStyleBackColor = true;
this.okButton.Click += new System.EventHandler(this.OKButton_Click);
//
// closeButton
//
this.closeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.closeButton.Location = new System.Drawing.Point(819, 598);
this.closeButton.Name = "closeButton";
this.closeButton.Size = new System.Drawing.Size(75, 23);
this.closeButton.TabIndex = 12;
this.closeButton.Text = "&Cancel";
this.closeButton.UseVisualStyleBackColor = true;
this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
//
// ObjectViewerForm
//
this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.closeButton;
this.ClientSize = new System.Drawing.Size(906, 628);
this.Controls.Add(this.closeButton);
this.Controls.Add(this.okButton);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.previewBox);
this.Controls.Add(this.parametersDataGridView);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ObjectViewerForm";
this.ShowInTaskbar = false;
this.Text = "Object Viewer";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ObjectViewerForm_FormClosed);
this.Load += new System.EventHandler(this.ObjectViewerForm_Load);
((System.ComponentModel.ISupportInitialize)(this.parametersDataGridView)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.previewBox)).EndInit();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.DataGridView parametersDataGridView;
private System.Windows.Forms.RadioButton physicalModelRadioButton;
private System.Windows.Forms.RadioButton analyticalModelRadioButton;
private System.Windows.Forms.PictureBox previewBox;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.ComboBox detailLevelComboBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ListBox viewListBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.Button closeButton;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.ComboBox viewDirectionComboBox;
}
}
Para.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Runtime.Serialization;
using Autodesk.Revit;
using Autodesk.Revit.DB;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// a class used to define a parameter of Element
/// </summary>
public class Para
{
private Parameter m_parameter; //one parameter of a element
/// <summary>
/// parameter's name
/// </summary>
public string ParaName
{
get
{
try
{
return m_parameter.Definition.Name;
}
catch
{
return null;
}
}
}
/// <summary>
/// parameter's value
/// </summary>
//public Object Value // jeremy
public string Value // jeremy
{
get
{
try
{
return GetParameterValue(m_parameter);
}
catch
{
return null;
}
}
set
{
try
{
SetParameterValue(m_parameter,value);
}
catch
{
}
}
}
/// <summary>
/// get parameter's value
/// </summary>
/// <param name="parameter">parameter of Element</param>
/// <returns>parameter's value include unit if have</returns>
public static string GetParameterValue(Parameter parameter) // jeremy
//public static Object GetParameterValue(Parameter parameter) // jeremy
{
switch (parameter.StorageType)
{
case StorageType.Double:
//get value with unit, AsDouble() can get value without unit
return parameter.AsValueString();
case StorageType.ElementId:
return parameter.AsElementId().IntegerValue.ToString();
case StorageType.Integer:
//get value with unit, AsInteger() can get value without unit
return parameter.AsValueString();
case StorageType.None:
return parameter.AsValueString();
case StorageType.String:
return parameter.AsString();
default:
return "";
}
}
/// <summary>
/// set parameter's value
/// </summary>
/// <param name="parameter">parameter of a Material</param>
/// <param name="value">
/// value will be set to parameter
/// </param>
public static void SetParameterValue(Parameter parameter, Object value)
{
//first,check whether this parameter is read only
if(parameter.IsReadOnly)
{
return;
}
switch (parameter.StorageType)
{
case StorageType.Double:
//set value with unit, Set() can set value without unit
parameter.SetValueString(value as string);
break;
case StorageType.ElementId:
Autodesk.Revit.DB.ElementId elementId = (Autodesk.Revit.DB.ElementId)(value);
parameter.Set(elementId);
break;
case StorageType.Integer:
//set value with unit, Set() can set value without unit
parameter.SetValueString(value as string);
break;
case StorageType.None:
parameter.SetValueString(value as string);
break;
case StorageType.String:
parameter.Set(value as string);
break;
default:
break;
}
}
/// <summary>
/// constructor of Para
/// </summary>
/// <param name="parameter"></param>
public Para(Parameter parameter)
{
m_parameter = parameter;
}
}
}
ParasFactory.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// a class used to create BindingList
/// </summary>
public class ParasFactory
{
private Element m_element; // element that selected in Revit by Mouse
private SortableBindingList<Para> m_parasList; //a list store parameters' information
/// <summary>
/// constructor of ParametersFactory
/// </summary>
/// <param name="element">the element of which parameters will be gotten</param>
public ParasFactory(Element element)
{
m_element = element;
m_parasList = new SortableBindingList<Para>();
//set m_parasList can be edit;
m_parasList.AllowEdit = true;
}
/// <summary>
/// add Para's instances to m_parasList, finally return it
/// </summary>
/// <returns></returns>
public SortableBindingList<Para> CreateParas()
{
try
{
ParameterSetIterator iterator = m_element.Parameters.ForwardIterator();
Parameter parameter;
iterator.Reset();
//use Iterator to loop, new a Para for each parameter and
//add it to m_parameter; if failed return null
for (; iterator.MoveNext(); )
{
parameter = iterator.Current as Parameter;
if (null != parameter)
{
m_parasList.Add(new Para(parameter));
}
}
}
catch (Exception e)
{
string errorText = "Create Paras failed: " + e.Message;
TaskDialog.Show("Revit", errorText);
return null;
}
return m_parasList;
}
}
}
Sketch.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections.ObjectModel;
using Autodesk.Revit.DB;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// provide methods to draw objects
/// </summary>
public class Sketch3D
{
// ratio of margin to canvas width
private const float MarginRatio = 0.1f;
// every frame distance to move the drawing
private const float MoveDistance = 2.0f;
// every frame ratio to zoom the drawing
private const float ZoomRatio = 0.05f;
// scale ratio of region showing the 2D geometry to the whole display region
private const float Drawing2DScale2D = 0.5f;
private List<PointF[]> m_curve3Ds = new List<PointF[]>(); // all 3D points
private List<PointF[]> m_curve2Ds = new List<PointF[]>(); // all 2D points
private Graphics3DData m_data3D; // 3D graphic data
private Graphics2DData m_data2D; // 2D graphic data
// defines a local geometric transform
private Matrix m_transform3D;
private Matrix m_transform2D;
// displayed BoundingBox in canvas
private RectangleF m_displayBBox = new RectangleF(0.0f, 0.0f, 10.0f, 10.0f);
/// <summary>
/// Displayed BoundingBox in canvas
/// </summary>
public RectangleF DisplayBBox
{
get
{
return m_displayBBox;
}
set
{
m_displayBBox = value;
Calculate2DTransform();
Calculate3DTransform();
UpdateDataAndEvent();
if (null != UpdateViewEvent)
{
UpdateViewEvent();
}
}
}
/// <summary>
/// 2D graphic data
/// </summary>
public Graphics2DData Data2D
{
get
{
return m_data2D;
}
set
{
m_data2D = value;
Calculate2DTransform();
UpdateDataAndEvent();
if (null != UpdateViewEvent)
{
UpdateViewEvent();
}
}
}
/// <summary>
/// 3D graphic data
/// </summary>
public Graphics3DData Data3D
{
get
{
return m_data3D;
}
set
{
m_data3D = value;
UpdateDataAndEvent();
if (null != UpdateViewEvent)
{
UpdateViewEvent();
}
}
}
/// <summary>
/// view data update
/// </summary>
public event UpdateViewDelegate UpdateViewEvent;
/// <summary>
/// The default constructor
/// </summary>
/// <param name="data3D">a list contain all the 3d data</param>
/// <param name="data2D">a list contain all the 3d data</param>
public Sketch3D(Graphics3DData data3D, Graphics2DData data2D)
{
m_data3D = data3D;
m_data2D = data2D;
Calculate3DTransform();
Calculate2DTransform();
UpdateDataAndEvent();
}
/// <summary>
/// draw the line contain in m_lines in 2d Preview
/// </summary>
/// <param name="graphics">Graphics to draw</param>
/// <returns></returns>
public void Draw(Graphics graphics)
{
if (m_data3D.NumPoints == 0 && m_data2D.NumPoints == 0)
{
graphics.Clear(System.Drawing.Color.LightGray);
return;
}
graphics.Clear(System.Drawing.Color.White);
DrawCurves(graphics, m_curve3Ds, m_transform3D, new Pen(System.Drawing.Color.DarkGreen));
DrawCurves(graphics, m_curve2Ds, m_transform2D, new Pen(System.Drawing.Color.DarkBlue));
if (m_data2D.NumPoints > 0)
{
GraphicsPath gPath = new GraphicsPath();
gPath.AddRectangle(m_data2D.BBox);
gPath.Transform(m_transform2D);
SolidBrush brush = new SolidBrush(System.Drawing.Color.FromArgb(70, System.Drawing.Color.LightSkyBlue));
graphics.FillPath(brush, gPath);
}
}
/// <summary>
/// zoom the displayed drawing in canvas
/// </summary>
/// <param name="zoomIn">true for zoom in, false for zoom out</param>
public void Zoom(bool zoomIn)
{
if (zoomIn)
{
m_transform3D.Scale(1f - ZoomRatio, 1f - ZoomRatio, MatrixOrder.Append);
}
else
{
m_transform3D.Scale(1f + ZoomRatio, 1f + ZoomRatio, MatrixOrder.Append);
}
if (null != UpdateViewEvent)
{
UpdateViewEvent();
}
}
/// <summary>
/// move view in horizontal direction
/// </summary>
/// <param name="left">left or right</param>
public void MoveX(bool left)
{
if (left)
{
m_transform3D.Translate(-MoveDistance, 0, MatrixOrder.Append);
}
else
{
m_transform3D.Translate(MoveDistance, 0, MatrixOrder.Append);
}
if (null != UpdateViewEvent)
{
UpdateViewEvent();
}
}
/// <summary>
/// move view in vertical direction
/// </summary>
/// <param name="up">up or down</param>
public void MoveY(bool up)
{
if (up)
{
m_transform3D.Translate(0, MoveDistance, MatrixOrder.Append);
}
else
{
m_transform3D.Translate(0, -MoveDistance, MatrixOrder.Append);
}
if (null != UpdateViewEvent)
{
UpdateViewEvent();
}
}
/// <summary>
/// update drawing data according and related Event
/// </summary>
private void UpdateDataAndEvent()
{
Initialize3DData();
Initialize2DData();
m_data3D.UpdateViewEvent += new UpdateViewDelegate(DataUpdateViewEvent);
}
/// <summary>
/// initialize 3D drawing data
/// </summary>
private void Initialize3DData()
{
m_curve3Ds.Clear();
foreach (List<Vector> vectors in m_data3D.ConstCurves)
{
PointF[] pnts = new PointF[vectors.Count];
m_curve3Ds.Add(pnts);
for (int i = 0; i < vectors.Count; i++)
{
pnts[i] = new PointF((float)vectors[i].X, (float)vectors[i].Y);
}
}
}
/// <summary>
/// initialize 2D drawing data
/// </summary>
private void Initialize2DData()
{
m_curve2Ds.Clear();
m_curve2Ds.AddRange(m_data2D.ConstCurves);
}
/// <summary>
/// Draw curves
/// </summary>
/// <param name="graphics">graphics handle</param>
/// <param name="curves">curves to be drawn</param>
/// <param name="transform">transform between canvas and graphic data</param>
/// <param name="pen">pen to draw</param>
private void DrawCurves(Graphics graphics, List<PointF[]> curves, Matrix transform, Pen pen)
{
foreach (PointF[] curve in curves)
{
GraphicsPath gPath = new GraphicsPath();
if (curve.Length == 0)
{
break;
}
if (curve.Length == 1)
{
gPath.AddArc(new RectangleF(curve[0], new SizeF(0.5f, 0.5f)), 0.0f, (float)Math.PI);
}
else
{
gPath.AddLines(curve);
}
gPath.Transform(transform);
graphics.DrawPath(pen, gPath);
}
}
/// <summary>
/// update according data when 3D data is updated
/// </summary>
private void DataUpdateViewEvent()
{
Initialize3DData();
if (null != UpdateViewEvent)
{
UpdateViewEvent();
}
}
/// <summary>
/// calculate the transform between canvas and 3D geometry objects
/// </summary>
private void Calculate3DTransform()
{
float previewWidth = m_displayBBox.Width;
float previewHeight = m_displayBBox.Height;
RectangleF bbox3D = ToBoundingBox2D(m_data3D.BBox);
PointF[] plgpts3D = CalculateCanvasRegion(previewWidth, previewHeight, bbox3D);
m_transform3D = new Matrix(PreTreatBBox(bbox3D), plgpts3D);
}
/// <summary>
/// calculate the transform between canvas and 2D geometry objects
/// </summary>
private void Calculate2DTransform()
{
float previewWidth = m_displayBBox.Width;
float previewHeight = m_displayBBox.Height;
float previewWidth2D = previewWidth * Drawing2DScale2D;
float previewHeight2D = previewHeight * Drawing2DScale2D;
PointF[] plgpts2D = CalculateCanvasRegion(previewWidth2D, previewHeight2D, m_data2D.BBox);
m_transform2D = new Matrix(PreTreatBBox(m_data2D.BBox), plgpts2D);
}
/// <summary>
/// pretreat BBoundingBox so that its height or width will be bigger than zero
/// </summary>
/// <param name="bbox"></param>
/// <returns></returns>
private RectangleF PreTreatBBox(RectangleF bbox)
{
const float EpsilonLen = 0.001f;
if (bbox.Height < EpsilonLen)
{
bbox.Height = 0.001f;
}
if (bbox.Width < EpsilonLen)
{
bbox.Width = 0.001f;
}
return bbox;
}
/// <summary>
/// get the display region, adjust the proportion and location
/// </summary>
/// <returns>upper-left, upper-right, and lower-left corners of the rectangle </returns>
private PointF[] CalculateCanvasRegion(float previewWidth, float previewHeigh, RectangleF bbox)
{
// get the area without margin
float realWidth = previewWidth * (1 - 2 * MarginRatio);
float realHeight = previewHeigh * (1 - 2 * MarginRatio);
float minX = previewWidth * MarginRatio;
float minY = previewHeigh * MarginRatio;
// ratio of width to height
float originRate = bbox.Width / bbox.Height;
float displayRate = realWidth / realHeight;
if (originRate > displayRate)
{
// display area in canvas need move to center in height
float goalHeight = realWidth / originRate;
minY = minY + (realHeight - goalHeight) / 2;
realHeight = goalHeight;
}
else
{
// display area in canvas need move to center in width
float goalWidth = realHeight * originRate;
minX = minX + (realWidth - goalWidth) / 2;
realWidth = goalWidth;
}
PointF[] plgpts = new PointF[3];
plgpts[0] = new PointF(minX, realHeight + minY); // upper-left point
plgpts[1] = new PointF(realWidth + minX, realHeight + minY); // upper-right point
plgpts[2] = new PointF(minX, minY); // lower-left point
return plgpts;
}
/// <summary>
/// Get X and Y data of 3D BoundingBox to creat a 2D BoundingBox
/// </summary>
/// <param name="bbox3D"></param>
/// <returns></returns>
private RectangleF ToBoundingBox2D(BoundingBoxXYZ bbox3D)
{
float left = (float)(bbox3D.Min.X);
float up = (float)(bbox3D.Min.Y);
float right = (float)(bbox3D.Max.X);
float down = (float)(bbox3D.Max.Y);
RectangleF bbox2D = new RectangleF(left, up, (right - left), (down - up));
return bbox2D;
}
}
}
UCS.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// This class stand for user coordinate system
/// </summary>
public class UCS
{
Vector m_origin = new Vector(0.0, 0.0, 0.0);
Vector m_xAxis = new Vector(1.0, 0.0, 0.0);
Vector m_yAxis = new Vector(0.0, 1.0, 0.0);
Vector m_zAxis = new Vector(0.0, 0.0, 1.0);
/// <summary>
/// constructor
/// </summary>
public UCS()
{
}
/// <summary>
/// Property to get origin of user coordinate system
/// </summary>
public Vector Origin
{
get
{
return m_origin;
}
set
{
m_origin = value;
}
}
/// <summary>
/// Property to get Axis(x,y,z) of User coordinate system
/// </summary>
/// <param name="index">indicate which Axis want be gotten</param>
/// <returns>information about the Axis</returns>
public Vector this[int index]
{
get
{
switch (index)
{
case 0:
return m_xAxis;
case 1:
return m_yAxis;
case 2:
return m_zAxis;
default:
throw new ArgumentOutOfRangeException();
}
}
}
/// <summary>
/// Property to get X Axis of user coordinate system
/// </summary>
public Vector XAxis
{
get
{
return m_xAxis;
}
}
/// <summary>
/// Property to get Y Axis of user coordinate system
/// </summary>
public Vector YAxis
{
get
{
return m_yAxis;
}
}
/// <summary>
/// Property to get Z Axis of user coordinate system
/// </summary>
public Vector ZAxis
{
get
{
return m_zAxis;
}
}
/// <summary>
/// The default constructor,
/// </summary>
public UCS(Vector origin, Vector xAxis, Vector yAxis)
: this(origin, xAxis, yAxis, true)
{
}
/// <summary>
/// constructor,
/// get a user coordinate system
/// </summary>
/// <param name="origin">origin of user coordinate system</param>
/// <param name="xAxis">xAxis of user coordinate system</param>
/// <param name="yAxis">yAxis of user coordinate system</param>
/// <param name="flag"></param>
public UCS(Vector origin, Vector xAxis, Vector yAxis, bool flag)
{
Vector x2 = xAxis / ~xAxis;
Vector y2 = yAxis / ~yAxis;
Vector z2 = x2 & y2;
if (~z2 < double.Epsilon)
{
throw new InvalidOperationException();
}
if (!flag)
{
z2 = -z2;
}
m_origin = origin;
m_xAxis = x2;
m_yAxis = y2;
m_zAxis = z2;
}
/// <summary>
/// Transform local coordinate to global coordinate
/// </summary>
/// <param name="arg">a vector which need to transform</param>
public Vector LC2GC(Vector arg)
{
Vector result = new Vector();
result.X =
arg.X * m_xAxis.X + arg.Y * m_yAxis.X + arg.Z * m_zAxis.X + m_origin.X;
result.Y =
arg.X * m_xAxis.Y + arg.Y * m_yAxis.Y + arg.Z * m_zAxis.Y + m_origin.Y;
result.Z =
arg.X * m_xAxis.Z + arg.Y * m_yAxis.Z + arg.Z * m_zAxis.Z + m_origin.Z;
return result;
}
/// <summary>
/// Transform global coordinate to local coordinate
/// </summary>
/// <param name="arg">a vector which need to transform</param>
public Vector GC2LC(Vector arg)
{
Vector result = new Vector();
arg = arg - m_origin;
result.X = m_xAxis * arg;
result.Y = m_yAxis * arg;
result.Z = m_zAxis * arg;
return result;
}
/// <summary>
/// add 2 UCS
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
/// <returns></returns>
public static UCS operator +(UCS lhs, UCS rhs)
{
Vector origin = lhs.Origin + rhs.Origin;
Vector[] left = new Vector[3];
Vector[] right = new Vector[3];
for (int i = 0; i < 3; i++)
{
left[i] = lhs[i];
right[i] = rhs[i];
}
Vector[] basis = Vector.MultiCross3X3Matrix(left, right);
return new UCS(origin, basis[0], basis[1]);
}
}
}
Vector.cs
//
// (C) Copyright 2003-2019 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.
//
using System;
using System.Collections.Generic;
using System.Text;
namespace Revit.SDK.Samples.ObjectViewer.CS
{
/// <summary>
/// Point class use to store point coordinate value
/// and get the value via (x, y ,z)property
/// </summary>
public struct Vector
{
//private member
private double m_x; //x coordinate of vector
private double m_y; //y coordinate of vector
private double m_z; //z coordinate of vector
/// <summary>
/// Property to get X coordinate
/// </summary>
public double X
{
get
{
return m_x;
}
set
{
m_x = value;
}
}
/// <summary>
/// Property to get Y coordinate
/// </summary>
public double Y
{
get
{
return m_y;
}
set
{
m_y = value;
}
}
/// <summary>
/// Property to get Z coordinate
/// </summary>
public double Z
{
get
{
return m_z;
}
set
{
m_z = value;
}
}
/// <summary>
/// Property to get x, y, z coordinate bu index 1, 2, 3
/// </summary>
public double this[int index]
{
get
{
switch (index)
{
case 0:
return m_x;
case 1:
return m_y;
case 2:
return m_z;
default:
throw new ArgumentOutOfRangeException();
}
}
set
{
switch (index)
{
case 0:
m_x = value;
break;
case 1:
m_y = value;
break;
case 2:
m_z = value;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
/// <summary>
/// copy constructor
/// </summary>
public Vector(Vector rhs)
{
m_x = rhs.X;
m_y = rhs.Y;
m_z = rhs.Z;
}
/// <summary>
/// constructor
/// </summary>
/// <param name="x">x coordinate of point</param>
/// <param name="y">y coordinate of point</param>
/// <param name="z">z coordinate of point</param>
public Vector(double x, double y, double z)
{
m_x = x;
m_y = y;
m_z = z;
}
/// <summary>
/// get Normal by vector
/// </summary>
public Vector GetNormal()
{
Vector direct = new Vector();
double len = GetLength();
if (len < double.Epsilon)
{
return new Vector();
}
direct.X = m_x / len;
direct.Y = m_y / len;
direct.Z = m_z / len;
return direct;
}
/// <summary>
/// add two vector
/// </summary>
/// <param name="lhs">first vector</param>
/// <param name="rhs">second vector</param>
/// <returns>add two vector</returns>
public static Vector operator +(Vector lhs, Vector rhs)
{
Vector result = new Vector(lhs);
result.X += rhs.X;
result.Y += rhs.Y;
result.Z += rhs.Z;
return result;
}
/// <summary>
/// subtraction of two vector
/// </summary>
/// <param name="lhs">first vector</param>
/// <param name="rhs">second vector</param>
/// <returns>subtraction of two vector</returns>
public static Vector operator -(Vector lhs, Vector rhs)
{
Vector result = new Vector(lhs);
result.X -= rhs.X;
result.Y -= rhs.Y;
result.Z -= rhs.Z;
return result;
}
/// <summary>
/// negative of vector
/// </summary>
/// <param name="lhs">vector</param>
/// <returns>negative of vector</returns>
public static Vector operator -(Vector lhs)
{
Vector result = new Vector(lhs);
result.X = -lhs.X;
result.Y = -lhs.Y;
result.Z = -lhs.Z;
return result;
}
/// <summary>
/// get normal vector of two vector
/// </summary>
/// <param name="lhs">first vector</param>
/// <param name="rhs">second vector</param>
/// <returns> normal vector of two vector</returns>
public static Vector operator &(Vector lhs, Vector rhs)
{
double v1 = lhs.X;
double v2 = lhs.Y;
double v3 = lhs.Z;
double u1 = rhs.X;
double u2 = rhs.Y;
double u3 = rhs.Z;
double x = v2 * u3 - v3 * u2;
double y = v3 * u1 - v1 * u3;
double z = v1 * u2 - v2 * u1;
return new Vector(x, y, z);
}
/// <summary>
/// get cross vector of two vector
/// </summary>
/// <param name="lhs">first vector</param>
/// <param name="rhs">second vector</param>
/// <returns> cross vector of two vector</returns>
public static double operator *(Vector lhs, Vector rhs)
{
return lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z;
}
/// <summary>
/// get vector multiply by an double value
/// </summary>
/// <param name="lhs">vector</param>
/// <param name="rhs">double value</param>
/// <returns> vector multiply by an double value</returns>
public static Vector operator *(Vector lhs, double rhs)
{
return new Vector(lhs.X * rhs, lhs.Y * rhs, lhs.Z * rhs);
}
/// <summary>
/// estimate whether two are unequal
/// </summary>
/// <param name="lhs">first vector</param>
/// <param name="rhs">second vector</param>
/// <returns> whether two are unequal</returns>
public static bool operator !=(Vector lhs, Vector rhs)
{
return !IsEqual(lhs, rhs);
}
/// <summary>
/// estimate whether two are equal
/// </summary>
/// <param name="lhs">first vector</param>
/// <param name="rhs">second vector</param>
/// <returns> whether two are equal</returns>
public static bool operator ==(Vector lhs, Vector rhs)
{
return IsEqual(lhs, rhs);
}
/// <summary>
/// get the length of vector
/// </summary>
/// <param name="lhs">vector</param>
/// <returns>length of vector</returns>
public static double operator ~(Vector lhs)
{
return lhs.GetLength();
}
/// <summary>
/// get vector divided by an double value
/// </summary>
/// <param name="lhs">vector</param>
/// <param name="rhs">double value</param>
/// <returns> vector divided by an double value</returns>
public static Vector operator /(Vector lhs, double rhs)
{
return new Vector(lhs.m_x / rhs, lhs.m_y / rhs, lhs.m_z / rhs);
}
/// <summary>
/// get angle of two vector
/// </summary>
/// <param name="lhs">first vector</param>
/// <param name="rhs">second vector</param>
/// <param name="acuteAngleDesired">
/// indicate whether get the acute angle of two angles between two vectors
/// </param>
/// <returns> angle of two vector</returns>
public static double GetAngleOf2Vectors(Vector lhs, Vector rhs, bool acuteAngleDesired)
{
double angle = Math.Acos(lhs.GetNormal() * rhs.GetNormal());
if (acuteAngleDesired && angle > Math.PI / 2)
{
angle = Math.PI - angle;
}
return angle;
}
/// <summary>
/// estimate whether two are equal
/// </summary>
/// <param name="obj">object which compare with</param>
/// <returns> whether two are equal</returns>
public override bool Equals(object obj)
{
try
{
Vector rhs = (Vector)obj;
return IsEqual(this, rhs);
}
catch
{
}
return false;
}
/// <summary>
/// Get HashCode
/// </summary>
public override int GetHashCode()
{
return m_x.GetHashCode() ^ m_y.GetHashCode() ^ m_z.GetHashCode();
}
/// <summary>
/// Get Length of vector
/// </summary>
public double GetLength()
{
return Math.Sqrt(m_x*m_x + m_y*m_y + m_z*m_z);
}
/// <summary>
/// estimate whether two vector are equal
/// </summary>
/// <param name="lhs">first vector</param>
/// <param name="rhs">second vector</param>
/// <returns> whether two are equal</returns>
private static bool IsEqual(Vector lhs, Vector rhs)
{
if (lhs.X == rhs.X && lhs.X == rhs.X && lhs.X == rhs.X)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// Cross multiply 2 3*3 Matrix
/// </summary>
/// <param name="m1"></param>
/// <param name="m2"></param>
/// <returns>result 3*3 Matrix</returns>
public static Vector[] MultiCross3X3Matrix(Vector[] m1, Vector[] m2)
{
Vector[] result = new Vector[3];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
switch (j)
{
case 0:
(result[i]).X += (m1[i])[k] * (m2[k])[j];
break;
case 1:
(result[i]).Y += (m1[i])[k] * (m2[k])[j];
break;
case 2:
(result[i]).Z += (m1[i])[k] * (m2[k])[j];
break;
default:
break;
}
}
}
}
return result;
}
}
}
版权所有 :无锡模信建筑科技有限公司 苏ICP备2021028830号-1 BIM建模|BIM技术应用|BIM软件开发
联系地址:江苏省无锡市新吴区龙山路4号B座705 手机:18761516598