当前位置: 首页 > article >正文

24. Revit API: 几何对象(五)- (Sur)Face

一、前言

虽然Face是GeometryObject的子类,Surface不是,但这两者之间还是挺有关联的,每个Face都有一个对应的Surface,类似于EdgeCurve的关系。

Surface是数学意义上的面,纯定义。

Face是几何形状(实体)上的面,是Surface上截取了一块区域,有边界。

所以,Revit种面、线、点之类的关系的计算,都是在Face上,而Surface主要是对“抽象”面的定义。


二、Face

Face及其子类都没有构造函数,只能通过Solid获取。类方法,就是常规的相交、投影、计算面上点的法向、切向等方法。

2.1. 方法

// UV
public BoundingBoxUV GetBoundingBox();  // 面UV包围盒
// 点坐标、法向、切向
public Transform ComputeDerivatives(UV point);  // 一阶导。可得点坐标、法向、切向
public XYZ ComputeNormal(UV point);	// 计算法向,上面方法的简化版
public XYZ Evaluate(UV params);  // 计算点坐标

public FaceSecondDerivatives ComputeSecondDerivatives(UV point);  // 二阶导

// 获取边、面
public IList<CurveLoop> GetEdgesAsCurveLoops(); 
public Surface GetSurface();


// 点、面、线关系
public IntersectionResult Project(XYZ point); // 点在面上的投影

public FaceIntersectionFaceResult Intersect(Face face);  // 面-面相交
public SetComparisonResult Intersect(Curve curve);  // 面-线相交

public bool IsInside(UV point);  // 指定UV是否在面上

// 三角细分
public Mesh Triangulate(double levelOfDetail)

UV咋解释呢,模型贴图知道吧,把图片映射到模型上。怎么让图片贴准呢,建模软件里有个叫“展UV”的功能。

讲不来讲不来,看【Wiki】。

下图是方正的、填满了UV的,还有那种没填满的,有的区域是无映射的。

下面模型/贴图来自【sketchfab.com】

2.2. 属性

属性如下:

  • OrientationMatchesSurfaceOrientation:表示面朝向与其Surface的是否为同向,用到Surface时需要依此判断。
  • (Has/Get)Region:这个“Region”没有接触过,具体是个什么东西还不知道。查了好一会儿,才在【这篇】中找到一点信息,但测试发现,这只是在平面图中创建填充(FilledRegion)的方法,与面没有关系😑。

三、Surface

Revit中,有这些面:

FaceSurface
平面PlanarFacePlane
圆柱面CylindricalFaceCylindricalSurface
圆锥面ConicalFaceConicalSurface
旋转面RevolvedFaceRevolvedSurface
直纹(曲)面RuledFaceRuledSurface
埃尔米特曲面HermiteFaceHermiteSurface
Nurbs简化为其它类型的面NurbsSurface(Data)

前面6种面都是从某个类派生的,最后的 NurbsSurface 则是例外,它只有NurbsSurfaceData这个数据类,且只在BRepBuilderSurfaceGeometry中使用,最后创建出的面,也会被简化,由其它类型表示。

Face没有构造函数,Surface的属性也会出现在其对应的Face中,就直接看Surface。

在Revit几何对象中,都有使用Frame,用以确定局部坐标系,在18. Revit API: 元素位置与变换这篇写过。

3.1. 平面(Plane)

平面有属性:面原点、面法向、X轴向、Y轴向。

构造方法:

  1. 由Frame创建
  2. 由面法向,和面上原点创建
  3. 由原点,和X、Y轴创建,法向为 Vector3.Corss(dir_x,dir_y)
  4. 由面上三点创建,面方向按点顺序和右手螺旋确定,原点为第一个点。

warning:三点创建时,X轴的方向是怎么确定的?

尝试了几种方式,算到的和读取的都不一样,不清楚Revit三点创建平面时,XY轴的确定方式。

3.2. 圆柱面(CylindricalSurface)

定义: S(u, v) = center + radius*cos(u)*xVec + radius*sin(u)*yVec + v*zVec

圆柱面比较简单,属性:圆半径、坐标系原点、中心轴、X轴向、Y轴向

后四个组合就算一个Frame。

构造方法:

  • 由 Frame + 半径 创建。

3.3. 圆锥面(ConicalSurface)

定义:S(u, v) = center + v*[sin(halfAngle)(cos(u)*xVec + sin(u)*yVec) + cos(halfAngle)*zVec]

圆锥面属性:半角(弧度制)、顶点、中心轴、X轴、Y轴

构造方法:

  • 由 Frame + 半角 创建

3.4. 旋转面(RevolvedSurface)

吐槽:就一个旋转方程,现在的我已经看不懂了,现在我只是个API调用仔。

旋转面的属性:原点、轴、X、Y,方法中获取旋转轮廓。

构造方法

  • 从Frame(或类似表示方位的东西)创建
  • 可以设置旋转的起始和终点角度

Info:①构造方法返回的是Surface类型,可能简化为其它类型的面;②可以设置起始角度,即不转满1圈。但属性中没有没有角度信息。

  1. 返回类型很好理解,比如:当轮廓为直线且与旋转轴平行时,就算创建一个圆柱面。
  2. 起始角度计算:
// 1. 从Surface本身无法获得,如下:

Curve curve = Line.CreateBound(new XYZ(10, 0, 0), new XYZ(9, 0, 10));
Surface revolvedSurface = RevolvedSurface.Create(new Frame(), curve, 0, Math.PI / 2); // 1/4 PI

Arc arc = Arc.Create(XYZ.Zero, 10, 0, Math.PI * 2, XYZ.BasisX, XYZ.BasisY); // 2 PI
IList<XYZ> points = arc.Tessellate();

string msg = string.Empty;
for (int i = 0; i < points.Count; i++)
{
    revolvedSurface.Project(points[i], out UV uv, out double dis);  // 期望有1/4的点投影距离为0,
    msg += $"{i}\t {dis.Round(5)}\t {uv.Round(4)}\r\n";
}
TaskDialog.Show("project", msg);

// 实际所有的 dis 全部 0,表示投影计算时,是投影到“完整转一圈”的面上

// 2. 如果是从Face上获取的旋转面,可以计算出该面的旋转角度

Reference faceRef = this.Selection.PickObject(ObjectType.Face);
GeometryObject geoObj = this.Document.GetElement(faceRef).GetGeometryObjectFromReference(faceRef);
RevolvedFace revolvedFace = geoObj as RevolvedFace;

XYZ startDir = revolvedFace.get_Radius(0);  // 这个获取起点轴方向 (Xvec)
// XYZ endDir = revolvedFace.get_Radius(1);  // Yvec

UV startUV = new UV(startDir.X, startDir.Y);
//UV endUV = new UV(endDir.X, endDir.Y);

double startAngle = UV.BasisU.AngleTo(startUV).RadToDeg();
//double endAngle = UV.BasisU.AngleTo(endUV).RadToDeg();

BoundingBoxUV uvBounding = revolvedFace.GetBoundingBox();

double rangeAngle = (uvBounding.Max.U - uvBounding.Min.U).RadToDeg();
double endAngle = startAngle + rangeAngle;

TaskDialog.Show("Revolved", $"RevolvedFace info:\r\n" +
    $"min:{uvBounding.Min}\r\n" +
    $"max:{uvBounding.Max}\r\n" +
    $"Xvec:{revolvedFace.get_Radius(0)}\r\n" +
    $"Yvec:{revolvedFace.get_Radius(1)}\r\n" +
    $"startAngle:{startAngle}\r\n" +
    $"range:{rangeAngle}\r\n" +
    $"endAngle:{endAngle}");

RevolvedFace上的Radius属性,表示的不是直径信息,而是(当前的)X轴向量和Y轴向量。

3.5. 直纹面(RuledSurface)

直纹(曲)面【Wiki】,没啥特殊的属性,创建结果可能简化为其它类型的面。

它有2类形式:① 两条Curve,② 点+Curve。

2个轨道,一根棍子搭在轨道上向前滚(按长度比例),滚过的区域就是直纹面。

结合Revit里的定义:S(u,v) = C1(u) + v⋅(C2(u)−C1(u))

3.6. NurbsSurface(Data)

Tips:NurbSpline叫非均匀有理样条线,参照这个问题链接。

Revit中并不支持NurbsSurface(会被简化),而是提供了一个对应的数据类NurbsSurfaceData

NurbsSurfaceData

① 该类只在BRepBuilderSurfaceGeometry中使用;

② 在ExportUtils工具类中提供了一个由面获取近似NurbsSurface数据的方法,只支持HermiteFaceRuledFace

我对这东西一知半解,就不多写了。

使用示例,请查看SDK下的示例“SDKSample/BRepBuilderExample/CreateNURBS.cs”,或者看【GitHub】,生成的模型长下面的样子。


四、总结

这篇,补充了几何对象中 Face、Surface 相关的内容,由于Face没有构造方法,主要写的是Surface。


http://www.kler.cn/a/316711.html

相关文章:

  • Ceph 中PG与PGP的概述
  • DAY112代码审计PHP开发框架POP链利用Yii反序列化POP利用链
  • 【计算机网络】UDP网络程序
  • HTTP常见的请求头有哪些?都有什么作用?在 Web 应用中使用这些请求头?
  • C# 模拟浏览器自操作(自动化办公)
  • 基于标签相关性的多标签学习
  • [Linux]Vi和Vim编辑器
  • 修改Git配置信息:用户名
  • linux第三课(linux中安装nginx与redis及SpringBoot集成redis)
  • 颍川陈氏——平民崛起的典范
  • 【AcWing】基础算法
  • Django 数据库配置以及字段设置详解
  • 移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.AVL树
  • C++(学习)2024.9.20
  • 【Kubernetes】常见面试题汇总(二十五)
  • 基于安全风险预测的自动驾驶自适应巡航控制优化
  • 智能BI项目第一期
  • 【网络】高级IO——poll版本TCP服务器
  • 11年408考研真题解析-计算机网络
  • js使用:
  • 银行项目测试,基础业务知识,一文全掌握!
  • 【C语言】__attribute__((constructor)) 和 __attribute__((destructor))详细解析
  • 基于微信小程序的商品展示+ssm(lw+演示+源码+运行)
  • 【论文速看】DL最新进展20240923-长尾综述、人脸防伪、图像分割
  • 非root安装Augustus报错解决
  • 速盾:凡科建站开cdn了吗?