Split Shape by Plane in OpenCASCADE
Split Shape by Plane in OpenCASCADE
Abstract. Sometimes you want to split a shape by plane or even split a shape by a B Spline surface, OpenCASCADE provide a feature class BRepFeat_SplitShape to implement the function. The paper give a sample code to split a cylinder by plane.
Key Words. Split Shape, BRep Feature Algorithms.
1. Introduction
OpenCASCADE提供了Boolean Operation实现了任意两个形状的交、并、差的布尔操作。但是如何实现用一个面将一个形状切割成两半呢?其实Boolean Operation中已经有求交分割的算法,但是没有直接提供一个分割的功能类,而是在BRepFeat_SplitShape提供了分割功能。
![]()
Figure 1. Split Cylinder by Plane
2. Code Demo
使用类BRepAlgoAPI_Section和类BRepFeat_SplitShape相结合来实现分割Split形状的功能。完整代码示例如下:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->/*
Copyright(C) 2017 Shing Liu(eryar@163.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
// Visual Studio 2013 & OpenCASCADE7.1.0
#include <gp_Pln.hxx>
#include <TopoDS.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepTools.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <BRepFeat_SplitShape.hxx>
#pragma comment(lib, "TKernel.lib")
#pragma comment(lib, "TKMath.lib")
#pragma comment(lib, "TKG2d.lib")
#pragma comment(lib, "TKG3d.lib")
#pragma comment(lib, "TKGeomBase.lib")
#pragma comment(lib, "TKGeomAlgo.lib")
#pragma comment(lib, "TKBRep.lib")
#pragma comment(lib, "TKTopAlgo.lib")
#pragma comment(lib, "TKBO.lib")
#pragma comment(lib, "TKPrim.lib")
#pragma comment(lib, "TKFeat.lib")
//! Test split a cylinder by plane.
//! You can use the algorithm to split other shapes.
void testSplit()
{
BRepPrimAPI_MakeCylinder aCylinderMaker(10.0, 20.0);
TopoDS_Shape aCylinder = aCylinderMaker.Shape();
// Build section by the split plane for the cylinder.
BRepAlgoAPI_Section aSection(aCylinder, gp_Pln(gp_Pnt(0.0, 0.0, 15.0), gp::DZ()), Standard_False);
aSection.ComputePCurveOn1(Standard_True);
aSection.Approximation(Standard_True);
aSection.Build();
// Split the cylinder shape.
BRepFeat_SplitShape aShapeSpliter(aCylinder);
for (TopExp_Explorer i(aSection.Shape(), TopAbs_EDGE); i.More(); i.Next())
{
TopoDS_Shape anEdge = i.Current();
TopoDS_Shape aFace;
if (aSection.HasAncestorFaceOn1(anEdge, aFace))
{
TopoDS_Edge E = TopoDS::Edge(anEdge);
TopoDS_Face F = TopoDS::Face(aFace);
aShapeSpliter.Add(E, F);
}
}
aShapeSpliter.Build();
// Rebuild left and right shape.
BRep_Builder aBuilder;
TopoDS_Compound aLeftCompound;
TopoDS_Compound aRightCompound;
aBuilder.MakeCompound(aLeftCompound);
aBuilder.MakeCompound(aRightCompound);
// Left shape.
TopTools_MapOfShape aLeftShapeMap;
const TopTools_ListOfShape& aLeftShapes = aShapeSpliter.Left();
for (auto i = aLeftShapes.cbegin(); i != aLeftShapes.cend(); i++)
{
aLeftShapeMap.Add(*i);
aBuilder.Add(aLeftCompound, *i);
}
// Right shape.
TopTools_IndexedMapOfShape aShapeMap;
TopExp::MapShapes(aShapeSpliter.Shape(), TopAbs_FACE, aShapeMap);
for (auto i = aShapeMap.cbegin(); i != aShapeMap.cend(); i++)
{
if (!aLeftShapeMap.Contains(*i))
{
aBuilder.Add(aRightCompound, *i);
}
}
// Output left and right shape.
BRepTools::Write(aLeftCompound, "d:/left.brep");
BRepTools::Write(aRightCompound, "d:/right.brep");
}
int main(int argc, char* argv[])
{
testSplit();
return 0;
}
先创建一个圆柱体,再使用类BRepAlgoAPI_Section将圆柱体用平面进行分割,最后使用类BRepFeat_SplitShape进行分类,得到切割后的形状及Left()形状,把切割后形状中的Left过滤后剩下就是切割另一半的形状;最后导出被平面切割后得到的两半形状。结果用动画演示如下:
![]()
Figure 2. Split Shape animation demo
3. Conclusion
OpenCASCADE提供类BRepFeat_SplitShape来实现对一个形状进行切割的功能,但是要配合BRepAlgoAPI_Section使用。因为Boolean Operation中已经实现了求交、分类的功能,所以在最新版本的源码7.2.0中已经将分割功能集成到了Boolean Operation中。分割后如果没有被改变的面还是原来的面。
Split Shape by Plane in OpenCASCADE的更多相关文章
- OpenCASCADE PCurve of Topological Face
OpenCASCADE PCurve of Topological Face eryar@163.com Abstract. OpenCASCADE provides a class BRepBuil ...
- Mesh Algorithm in OpenCascade
Mesh Algorithm in OpenCascade eryar@163.com Abstract. Rendering a generic surface is a two steps pro ...
- FreeType in OpenCASCADE
FreeType in OpenCASCADE eryar@163.com Abstract. FreeType is required for text display in the 3D view ...
- Egret中使用P2物理引擎
游戏中的对象按照物理规律移动,体现重力.引力.反作用力.加速度等物体特性,实现自由落体.摇摆运动.抛物线运动,以及物理碰撞现象的模拟.用于模拟物理碰撞.物理运动的引擎称为物理引擎. 来自瑞典斯德哥尔摩 ...
- 那些我离不开的 Sketch 插件
当谈论到插件时,我是一名极客.各种新颖的 Sketch 插件层出不穷,但是有那么几个是我怎么也离不开的. Sketch 运行器 多层的插件菜单再也不会影响我的效率了. 我推迟了好几年才使用这个插件,因 ...
- p2 形状
形状是物理引擎进行碰撞模拟计算的依据,是刚体最基本的属性. P2中使用Shape类来表示形状,通过刚体的addShape()方法,将形状添加到刚体中之后, 就可以随着刚体的移动.旋转不断更新,并进行碰 ...
- css3动画效果:3 3D动画
立方体旋转动画效果 css #container{ width: 400px; height: 400px; ; ; -webkit-perspective-origin:50% 225px; per ...
- OpenCASCADE Shape Location
OpenCASCADE Shape Location eryar@163.com Abstract. The TopLoc package of OpenCASCADE gives resources ...
- OpenCascade Shape Representation in OpenSceneGraph
OpenCascade Shape Representation in OpenSceneGraph eryar@163.com 摘要Abstract:本文通过程序实例,将OpenCascade中的拓 ...
随机推荐
- invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
Column 'dbo.tbm_vie_View.ViewID' is invalid in the select list because it is not contained in either ...
- 3.c语言结构体成员内存对齐详解
一.关键一点 最关键的一点:结构体在内存中是一个矩形,而不是一个不规则形状 二.编程实战 #include <stdlib.h> #include <stdio.h> stru ...
- c# static 常量
1 关键字 static 修饰 类 字段 属性 方法 ,标记static的就不用创建类的实例调用了,直接通过类名点出来 2 用于变量前,表示每次重新使用该变量所在的方法,类或者自定义的类时,变量的值 ...
- codeforces 540 B School Marks【贪心】
题意:一共n个数,给出其中k个数,要求这n个数的中位数为y,这n个数的和不超过x,补全剩下的n-k个数 先统计给出的k个数里面比中位数小的数, 如果cnt<=n/2,说明中位数还没有出现,把这n ...
- sql笔试题-1
在oracle下sql:比较巧妙地是group by 部分 E from (select a.team,b.y from nba a,nba b ) c group by (c.y-rownum) o ...
- DedeCMS文章编辑不更新时间1970年1月1日
在修改文章或者后期优化的时候,织梦dedecms5.7版本存在一个问题,修改文章的同时也修改了文章的发布时间,这个功能可能有些人比较需要,但同时也有些站长朋友又不需要,因为我们编辑某个文章的时候,发现 ...
- Timestamp 转 date
Timestamp startTime = new Timestamp(new Date().getTime());
- 【模板】2-SAT 问题(2-SAT)
[模板]2-SAT 问题 题目背景 2-SAT 问题 模板 题目描述 有n个布尔变量 \(x_1\) ~ \(x_n\) ,另有m个需要满足的条件,每个条件的形式都是" \(x_i\) ...
- C++ 容器(一):顺序容器简介
C++提供了使用抽象进行高效编程的方式,标准库中定义了许多容器类以及一系列泛型函数,使程序员可以更加简洁.抽象和有效地编写程序,其中包括:顺序容器,关联容器和泛型算法.本文将简介顺序容器(vector ...
- Intent传递对象——Serializable和Parcelable差别
前两篇文章讨论了Serializable和Parcelable实现Intent之间传递对象和对象数组的方式.两种方法实现上相似,效果一致,怎么选择用哪种方法实现呢? Intent在不同的组件中传递对象 ...