Skip to content

Commit a4c3fdf

Browse files
author
aothms
committed
Add support for IfcSweptDiskSolid
1 parent b235320 commit a4c3fdf

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

src/ifcgeom/IfcGeomShapes.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,81 @@ bool IfcGeom::convert(const IfcSchema::IfcSurfaceCurveSweptAreaSolid::ptr l, Top
637637
return true;
638638
}
639639

640+
bool IfcGeom::convert(const IfcSchema::IfcSweptDiskSolid::ptr l, TopoDS_Shape& shape) {
641+
TopoDS_Wire wire, section1, section2;
642+
643+
const bool hasInnerRadius = l->hasInnerRadius();
644+
645+
if (!IfcGeom::convert_wire(l->Directrix(), wire)) {
646+
return false;
647+
}
648+
649+
gp_Ax2 directrix;
650+
{
651+
gp_Pnt directrix_origin;
652+
gp_Vec directrix_tangent;
653+
TopExp_Explorer exp(wire, TopAbs_EDGE);
654+
TopoDS_Edge edge = TopoDS::Edge(exp.Current());
655+
double u0, u1;
656+
Handle(Geom_Curve) crv = BRep_Tool::Curve(edge, u0, u1);
657+
crv->D1(u0, directrix_origin, directrix_tangent);
658+
directrix = gp_Ax2(directrix_origin, directrix_tangent);
659+
}
660+
661+
const double r1 = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
662+
Handle(Geom_Circle) circle = new Geom_Circle(directrix, r1);
663+
section1 = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(circle));
664+
665+
if (hasInnerRadius) {
666+
const double r2 = l->InnerRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
667+
Handle(Geom_Circle) circle = new Geom_Circle(directrix, r2);
668+
section2 = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(circle));
669+
}
670+
671+
// NB: Note that StartParam and EndParam param are ignored and the assumption is
672+
// made that the parametric range over which to be swept matches the IfcCurve in
673+
// its entirety.
674+
// NB2: Contrary to IfcSurfaceCurveSweptAreaSolid the transition mode has been
675+
// set to create round corners as this has proven to work better with the types
676+
// of directrices encountered, which do not necessarily conform to a surface.
677+
{ BRepOffsetAPI_MakePipeShell builder(wire);
678+
builder.Add(section1);
679+
builder.SetTransitionMode(BRepBuilderAPI_RoundCorner);
680+
builder.Build();
681+
builder.MakeSolid();
682+
shape = builder.Shape(); }
683+
684+
if (hasInnerRadius) {
685+
BRepOffsetAPI_MakePipeShell builder(wire);
686+
builder.Add(section2);
687+
builder.SetTransitionMode(BRepBuilderAPI_RoundCorner);
688+
builder.Build();
689+
builder.MakeSolid();
690+
TopoDS_Shape inner = builder.Shape();
691+
692+
BRepAlgoAPI_Cut brep_cut(shape, inner);
693+
bool is_valid = false;
694+
if (brep_cut.IsDone()) {
695+
TopoDS_Shape result = brep_cut;
696+
697+
ShapeFix_Shape fix(result);
698+
fix.Perform();
699+
result = fix.Shape();
700+
701+
is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
702+
if (is_valid) {
703+
shape = result;
704+
}
705+
}
706+
707+
if (!is_valid) {
708+
Logger::Message(Logger::LOG_WARNING, "Failed to subtract inner radius void for:", l->entity);
709+
}
710+
}
711+
712+
return true;
713+
}
714+
640715
#ifdef USE_IFC4
641716

642717
bool IfcGeom::convert(const IfcSchema::IfcCylindricalSurface::ptr l, TopoDS_Shape& face) {

src/ifcgeom/IfcRegister.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ SHAPE(IfcCsgSolid);
6767
SHAPE(IfcCurveBoundedPlane);
6868
SHAPE(IfcRectangularTrimmedSurface);
6969
SHAPE(IfcSurfaceCurveSweptAreaSolid);
70+
SHAPE(IfcSweptDiskSolid);
7071
#ifdef USE_IFC4
7172
SHAPE(IfcCylindricalSurface);
7273
#endif

0 commit comments

Comments
 (0)