十二、Revit几何编程核心
-
几何运算核心
基础元素
变换矩阵
这里需补充学习高等数学向量空间和矩阵的知识
-
实战:求两条线段的交点
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ElementCUD
{
/// <summary>
/// 创建两条线,求交点
/// </summary>
[Transaction(TransactionMode.Manual)]
public class GeometryCalculation : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
//创建三个点
var point1 = new XYZ(2, 0, 0);
var point2 = new XYZ(0, 2, 0);
var point3 = new XYZ(3, 3, 0);
//创建两条线段
var line1 = Line.CreateBound(point1, point2);
var line2 = Line.CreateBound(XYZ.Zero, point3);
//求两条线段的交点,查阅API文档,可以采用
//public SetComparisonResult Intersect(Curve curve,out IntersectionResultArray resultArray)方法实现
//定义交集数组
IntersectionResultArray results;
//两条线相交
var result = line1.Intersect(line2, out results);
//判断结果是否为交点,是则输出它
if (result == SetComparisonResult.Overlap) //判断两个集合的交集非空(这里求交点的思想,实际上是用集合之间的交集思想来实现的)
{
var point = results.get_Item(0).XYZPoint; //获取交点坐标(实际上通过获取交集数组的第一个元素的三维空间坐标实现)
TaskDialog.Show("ZZW", point.ToString());
}
return Result.Succeeded;
}
}
}
- 实战:创建一个集合拉伸体
- Line.CreateBound()方法创建线段,是有长度要求的。当要创建的线段长度太小不满足commandData.Application.Application.ShortCurveTolerance的要求时,无法创建。这个值大概是0.68mm
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ElementCUD
{
[Transaction(TransactionMode.Manual)]
public class GeometryCalculation1 : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
//获取当前文档
var doc = commandData.Application.ActiveUIDocument.Document;
//创建4个点
var point1 = new XYZ(0, 0, 0);
var point2 = new XYZ(5, 0, 0);
var point3 = new XYZ(5, 5, 0);
var point4 = new XYZ(0, 5, 0);
//创建4条线段(这里一定要注意,为下一步创建闭合曲线做准备,这里的线段的点应该都是头尾交错,即前一个点的尾为下一条线段的头)
var line1 = Line.CreateBound(point1, point2);
var line2 = Line.CreateBound(point2, point3);
var line3 = Line.CreateBound(point3, point4);
var line4 = Line.CreateBound(point4, point1);
//创建曲线环curveloop
var curveloops = new CurveLoop();
curveloops.Append(line1);
curveloops.Append(line2);
curveloops.Append(line3);
curveloops.Append(line4);
//将曲线环平移
var transfoorm = Transform.CreateTranslation(new XYZ(5, 5, 0));
curveloops.Transform(transfoorm);
//创建一个拉伸立方体,通过GeometryCreationUtilities这个类来实现创建实体
//查询文档可用public static Solid CreateExtrusionGeometry(IList<CurveLoop> profileLoops(CurveLoop集合),XYZ extrusionDir(拉伸方向),double extrusionDist(拉伸值))
var solid = GeometryCreationUtilities.CreateExtrusionGeometry(new List<CurveLoop> {curveloops},XYZ.BasisZ,10);
//现在创建的实体都在内存中,还未放到文档里面,这里需要创建一个事务
var transaction = new Transaction(doc,"创建一个拉伸几何体");
//启动事务
transaction.Start();
//创建一个几何体,这里使用DirectShape类来实现。
//此类用于存储外部创建的几何形状。主要用途是从其他数据格式(如 IFC 或 STEP)导入形状。
var shape = DirectShape.CreateElement(doc,new ElementId(BuiltInCategory.OST_GenericModel)); //储存外部模型为常规模型
//设定模型的形状(这里用DirectShape类的setshape()方法实现)
shape.SetShape(new GeometryObject[] { solid });
//提交事务
transaction.Commit();
return Result.Succeeded;
}
}
}
- 实例:在上述创建的几何拉伸体上添加扩展数据
- Revit二次开发过程中,需要将相关信息存储到RVT文件中,再次打开RVT的时候,可以通过读取这些信息,知道当前构件的基本状态,或者将一个特殊的信息存储到RVT文件中,从Revit2012开始引入了扩展存储这个新技术,就是可以把一些数据存储在Revit中的某一个对象上。且这个存储操作,只能通过编程实现,无法通过Revit的软件操作实现。这个大大增加了我们数据存储的优势,可以把任何的数据保存在Revit中的任何一个对象上,数据始终跟着这个Rvt文件走,不会丢失。 而且存储的数据可以设置访问权限。对于保密数据可以只能是你自己的程序读取,或只有具有特殊的开发者代号的程序才能访问,对于数据的保密性非常有帮助。
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ElementCUD
{
[Transaction(TransactionMode.Manual)]
public class GeometryCalculation1 : IExternalCommand
{
//生成一个schemaGUID(全局唯一标识符)
private static Guid _schemaGUID = new Guid("F6A4F7D3-87A6-4F0F-A877-B91BB4667F18");
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
//获取当前文档
var doc = commandData.Application.ActiveUIDocument.Document;
//创建4个点
var point1 = new XYZ(0, 0, 0);
var point2 = new XYZ(5, 0, 0);
var point3 = new XYZ(5, 5, 0);
var point4 = new XYZ(0, 5, 0);
//创建4条线段(这里一定要注意,为下一步创建闭合曲线做准备,这里的线段的点应该都是头尾交错,即前一个点的尾为下一条线段的头)
var line1 = Line.CreateBound(point1, point2);
var line2 = Line.CreateBound(point2, point3);
var line3 = Line.CreateBound(point3, point4);
var line4 = Line.CreateBound(point4, point1);
//创建曲线环curveloop
var curveloops = new CurveLoop();
curveloops.Append(line1);
curveloops.Append(line2);
curveloops.Append(line3);
curveloops.Append(line4);
//将曲线环平移
var transfoorm = Transform.CreateTranslation(new XYZ(5, 5, 0));
curveloops.Transform(transfoorm);
//创建一个拉伸立方体,通过GeometryCreationUtilities这个类来实现创建实体
//查询文档可用public static Solid CreateExtrusionGeometry(IList<CurveLoop> profileLoops(CurveLoop集合),XYZ extrusionDir(拉伸方向),double extrusionDist(拉伸值))
var solid = GeometryCreationUtilities.CreateExtrusionGeometry(new List<CurveLoop> {curveloops},XYZ.BasisZ,10);
//现在创建的实体都在内存中,还未放到文档里面,这里需要创建一个事务
var transaction = new Transaction(doc,"创建一个拉伸几何体");
//启动事务
transaction.Start();
//创建一个几何体,这里使用DirectShape类来实现。
//此类用于存储外部创建的几何形状。主要用途是从其他数据格式(如 IFC 或 STEP)导入形状。
var shape = DirectShape.CreateElement(doc,new ElementId(BuiltInCategory.OST_GenericModel)); //储存外部模型为常规模型
//设定模型的形状(这里用DirectShape类的setshape()方法实现)
shape.SetShape(new GeometryObject[] { solid });
//给生成的这个几何拉伸体添加一些扩展信息(用类Schema(框架)、Entity(实体)、Field(字段)、DataStorage(存储对象)实现)
var schema = Schema.Lookup(_schemaGUID);
if (schema == null) //如果schema为空,则创建一个
{
//创建一个SchemaBuilder(感觉就像是创建一个身份证)
var schemaBulider = new SchemaBuilder(_schemaGUID);
//设置读取权限
schemaBulider.SetReadAccessLevel(AccessLevel.Public);
//设置写入权限
schemaBulider.SetWriteAccessLevel(AccessLevel.Public);
//设置架构名称
schemaBulider.SetSchemaName("zzw");
//设置说明性文字
schemaBulider.SetDocumentation("唯一身份识别");
//添加字段
var fieldBulider = schemaBulider.AddSimpleField("Name", typeof(String));
//完成schema定义
schema = schemaBulider.Finish();
}
//创建数据实体Entity(通过架构填充自己需要的内容)
var entity = new Entity(schema);
//添加名字
var name = schema.GetField("Name");
entity.Set(name, "TychoBoom");
//把实体Entity赋值给前面创建的shape几何拉伸体
shape.SetEntity(entity);
//用过滤器+linq语句筛选出可能已经创建过的storage
var datastoragelist = from element in new FilteredElementCollector
(doc).OfClass(typeof(DataStorage))
let storage = element as DataStorage
where storage.GetEntitySchemaGuids().Contains(_schemaGUID)
select storage;
var datastorage = datastoragelist.FirstOrDefault();
if (datastorage == null)
{
//把信息储存到整个文档中(通过DataStorage实现)
datastorage = DataStorage.Create(doc);
}
//把实体Entity赋值给datastorage
datastorage.SetEntity(entity);
//读取这个信息
//第一步:找到schema
var dataEntity = datastorage.GetEntity(schema);
//第二步:找到filed
var filed = dataEntity.Schema.GetField("Name");
//第三步:在filed中找到信息
var result = dataEntity.Get<string>(filed);
//第四步:展示出信息
TaskDialog.Show("ZZW", "名字是" + result);
//提交事务
transaction.Commit();
return Result.Succeeded;
}
}
}