使用 Revit 在剖视图中镜像细节 API
Mirroring details inside a section view using the Revit API
我在截面视图中有一些细节线,我想在该截面的 CropBox
的中点进行镜像。我正在使用 ElementTransformUtils.MirrorElements
来尝试完成此操作。但是,我还没有找到在其上镜像细节线的正确平面。我试过 Plane.CreateByNormalAndOrigin(section.ViewDirection, section.Origin)
和 detailLine.SketchPlane.GetPlane()
,但其中 none 已经反映了详细信息行。
完成此任务的正确方法是什么?
是的,您提到的平面不会像您期望的那样镜像。
我假设您需要一个垂直于详图线的平面。
这将镜像一条水平细节线,如您从右到左显示的那样,反之亦然。
您可以从细节线本身确定镜像平面法线和原点:
XYZ p = detail line start point
XYZ q = detail line end point
XYZ normal = q - p
Plane plane = Plane.CreateByNormalAndOrigin(p, normal)
或多或少...
我能够让我的详细信息反映在 ViewSection.CropBox
的中点,但它相当复杂。我发现 ViewSection.Origin
是项目坐标系中的一个点。另一方面,ViewSection.CropBox
不会为您提供项目坐标系中的最小值和最大值,而是为您提供 CropBox 相对于 ViewSection.Origin
的位置。使用 ViewSection.Origin
和 ViewSection.CropBox
您可以计算项目坐标系中 ViewSection.CropBox
的最小值和最大值。最后,您需要使用这些最小值和最大值来找到 ViewSection.CropBox
的中点,然后在该点上进行镜像。
这是我使用的一些帮助程序类,以便我可以使用单个函数找到最小值和最大值
public enum PointComponent
{
Invalid,
X,
Y,
Z
}
public enum MinOrMax
{
Invalid,
Min,
Max
}
这是查找 CropBox 的最小值或最大值的 X、Y 或 Z 分量的函数:
private double GetSectionCropBoxOrigin(ViewSection section,
PointComponent pointComponent, MinOrMax minOrMax)
{
double cropBoxOrigin;
double sectionOrigin, viewDirection, upDirection, rightDirection;
switch (pointComponent)
{
case PointComponent.X:
sectionOrigin = section.Origin.X;
viewDirection = section.ViewDirection.X;
upDirection = section.UpDirection.X;
rightDirection = section.RightDirection.X;
break;
case PointComponent.Y:
sectionOrigin = section.Origin.Y;
viewDirection = section.ViewDirection.Y;
upDirection = section.UpDirection.Y;
rightDirection = section.RightDirection.Y;
break;
case PointComponent.Z:
sectionOrigin = section.Origin.Z;
viewDirection = section.ViewDirection.Z;
upDirection = section.UpDirection.Z;
rightDirection = section.RightDirection.Z;
break;
default:
throw new InvalidOperationException();
}
double cropX, cropY;
switch (minOrMax)
{
case MinOrMax.Min:
cropX = section.CropBox.Min.X;
cropY = section.CropBox.Min.Y;
break;
case MinOrMax.Max:
cropX = section.CropBox.Max.X;
cropY = section.CropBox.Max.Y;
break;
default:
throw new InvalidOperationException();
}
if (Math.Abs(viewDirection) == 1)
cropBoxOrigin = sectionOrigin;
else if (Math.Abs(upDirection) == 1)
cropBoxOrigin = sectionOrigin + (cropY * upDirection);
else if (Math.Abs(rightDirection) == 1)
cropBoxOrigin = sectionOrigin + (cropX * rightDirection);
else
throw new InvalidOperationException();
return cropBoxOrigin;
}
请注意,对于 PointComponent.Z
,我们不使用最小值和最大值之间的中点,而是使用原点。这是因为即使我们指定了 CropBox
深度并且细节工作位于与 ViewSection.Origin
.
相同的深度,我们的细节工作仅存在于 2D 中
这是我用来获取中点的代码:
private XYZ Get3dMidpoint(XYZ start, XYZ end)
{
double x = (start.X + end.X) / 2.0;
double y = (start.Y + end.Y) / 2.0;
double z = (start.Z + end.Z) / 2.0;
return new XYZ(x, y, z);
}
最后是将所有内容组合在一起并获得镜像平面的代码:
XYZ cropBoxMinInGlobalCoordinates = new XYZ(
GetSectionCropBoxOrigin(section, PointComponent.X, MinOrMax.Min),
GetSectionCropBoxOrigin(section, PointComponent.Y, MinOrMax.Min),
GetSectionCropBoxOrigin(section, PointComponent.Z, MinOrMax.Min)
);
XYZ cropBoxMaxInGlobalCoordinates = new XYZ(
GetSectionCropBoxOrigin(section, PointComponent.X, MinOrMax.Max),
GetSectionCropBoxOrigin(section, PointComponent.Y, MinOrMax.Max),
GetSectionCropBoxOrigin(section, PointComponent.Z, MinOrMax.Max)
);
XYZ cropBoxOriginInGlobalCoordinates =
Get3dMidpoint(cropBoxMinInGlobalCoordinates, cropBoxMaxInGlobalCoordinates);
Plane mirrorPlane =
Plane.CreateByNormalAndOrigin(section.RightDirection, cropBoxOriginInGlobalCoordinates);
我在截面视图中有一些细节线,我想在该截面的 CropBox
的中点进行镜像。我正在使用 ElementTransformUtils.MirrorElements
来尝试完成此操作。但是,我还没有找到在其上镜像细节线的正确平面。我试过 Plane.CreateByNormalAndOrigin(section.ViewDirection, section.Origin)
和 detailLine.SketchPlane.GetPlane()
,但其中 none 已经反映了详细信息行。
完成此任务的正确方法是什么?
是的,您提到的平面不会像您期望的那样镜像。
我假设您需要一个垂直于详图线的平面。
这将镜像一条水平细节线,如您从右到左显示的那样,反之亦然。
您可以从细节线本身确定镜像平面法线和原点:
XYZ p = detail line start point
XYZ q = detail line end point
XYZ normal = q - p
Plane plane = Plane.CreateByNormalAndOrigin(p, normal)
或多或少...
我能够让我的详细信息反映在 ViewSection.CropBox
的中点,但它相当复杂。我发现 ViewSection.Origin
是项目坐标系中的一个点。另一方面,ViewSection.CropBox
不会为您提供项目坐标系中的最小值和最大值,而是为您提供 CropBox 相对于 ViewSection.Origin
的位置。使用 ViewSection.Origin
和 ViewSection.CropBox
您可以计算项目坐标系中 ViewSection.CropBox
的最小值和最大值。最后,您需要使用这些最小值和最大值来找到 ViewSection.CropBox
的中点,然后在该点上进行镜像。
这是我使用的一些帮助程序类,以便我可以使用单个函数找到最小值和最大值
public enum PointComponent
{
Invalid,
X,
Y,
Z
}
public enum MinOrMax
{
Invalid,
Min,
Max
}
这是查找 CropBox 的最小值或最大值的 X、Y 或 Z 分量的函数:
private double GetSectionCropBoxOrigin(ViewSection section,
PointComponent pointComponent, MinOrMax minOrMax)
{
double cropBoxOrigin;
double sectionOrigin, viewDirection, upDirection, rightDirection;
switch (pointComponent)
{
case PointComponent.X:
sectionOrigin = section.Origin.X;
viewDirection = section.ViewDirection.X;
upDirection = section.UpDirection.X;
rightDirection = section.RightDirection.X;
break;
case PointComponent.Y:
sectionOrigin = section.Origin.Y;
viewDirection = section.ViewDirection.Y;
upDirection = section.UpDirection.Y;
rightDirection = section.RightDirection.Y;
break;
case PointComponent.Z:
sectionOrigin = section.Origin.Z;
viewDirection = section.ViewDirection.Z;
upDirection = section.UpDirection.Z;
rightDirection = section.RightDirection.Z;
break;
default:
throw new InvalidOperationException();
}
double cropX, cropY;
switch (minOrMax)
{
case MinOrMax.Min:
cropX = section.CropBox.Min.X;
cropY = section.CropBox.Min.Y;
break;
case MinOrMax.Max:
cropX = section.CropBox.Max.X;
cropY = section.CropBox.Max.Y;
break;
default:
throw new InvalidOperationException();
}
if (Math.Abs(viewDirection) == 1)
cropBoxOrigin = sectionOrigin;
else if (Math.Abs(upDirection) == 1)
cropBoxOrigin = sectionOrigin + (cropY * upDirection);
else if (Math.Abs(rightDirection) == 1)
cropBoxOrigin = sectionOrigin + (cropX * rightDirection);
else
throw new InvalidOperationException();
return cropBoxOrigin;
}
请注意,对于 PointComponent.Z
,我们不使用最小值和最大值之间的中点,而是使用原点。这是因为即使我们指定了 CropBox
深度并且细节工作位于与 ViewSection.Origin
.
这是我用来获取中点的代码:
private XYZ Get3dMidpoint(XYZ start, XYZ end)
{
double x = (start.X + end.X) / 2.0;
double y = (start.Y + end.Y) / 2.0;
double z = (start.Z + end.Z) / 2.0;
return new XYZ(x, y, z);
}
最后是将所有内容组合在一起并获得镜像平面的代码:
XYZ cropBoxMinInGlobalCoordinates = new XYZ(
GetSectionCropBoxOrigin(section, PointComponent.X, MinOrMax.Min),
GetSectionCropBoxOrigin(section, PointComponent.Y, MinOrMax.Min),
GetSectionCropBoxOrigin(section, PointComponent.Z, MinOrMax.Min)
);
XYZ cropBoxMaxInGlobalCoordinates = new XYZ(
GetSectionCropBoxOrigin(section, PointComponent.X, MinOrMax.Max),
GetSectionCropBoxOrigin(section, PointComponent.Y, MinOrMax.Max),
GetSectionCropBoxOrigin(section, PointComponent.Z, MinOrMax.Max)
);
XYZ cropBoxOriginInGlobalCoordinates =
Get3dMidpoint(cropBoxMinInGlobalCoordinates, cropBoxMaxInGlobalCoordinates);
Plane mirrorPlane =
Plane.CreateByNormalAndOrigin(section.RightDirection, cropBoxOriginInGlobalCoordinates);