1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00
occt/src/BRepFeat/BRepFeat_MakeDPrism.cxx
dpasukhi 52cbf180cd 0033375: Coding - Static Analyzing processing. Performance
Performance update applied:
  - moving to const reference as much as possible
Result of CLANG_TIDY (static analyzing filter: perform*)
2023-07-21 16:33:47 +01:00

1179 lines
34 KiB
C++

// Created on: 1996-09-03
// Created by: Olga KOULECHOVA
// Copyright (c) 1996-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Bnd_Box.hxx>
#include <BRepAlgo.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include <BRepBndLib.hxx>
#include <BRepFeat.hxx>
#include <BRepFeat_MakeDPrism.hxx>
#include <BRepLib.hxx>
#include <BRepLib_MakeFace.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepTools.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_Surface.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <LocOpe.hxx>
#include <LocOpe_CSIntersector.hxx>
#include <LocOpe_DPrism.hxx>
#include <LocOpe_PntFace.hxx>
#include <Precision.hxx>
#include <Standard_ConstructionError.hxx>
#include <TColGeom_SequenceOfCurve.hxx>
#include <TColgp_SequenceOfPnt.hxx>
#include <TopAbs.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Solid.hxx>
#include <TopTools_MapOfShape.hxx>
#ifdef OCCT_DEBUG
extern Standard_Boolean BRepFeat_GettraceFEAT();
#endif
static void MajMap(const TopoDS_Shape&,
const LocOpe_DPrism&,
TopTools_DataMapOfShapeListOfShape&, // myMap
TopoDS_Shape&, // myFShape
TopoDS_Shape&); // myLShape
static Standard_Real HeightMax(const TopoDS_Shape& theSbase,
const TopoDS_Face& theSkface,
const TopoDS_Shape& theSFrom,
const TopoDS_Shape& theSUntil);
static Standard_Integer SensOfPrism(const Handle(Geom_Curve)& C,
const TopoDS_Shape& Until);
static Handle(Geom_Curve) TestCurve(const TopoDS_Face&);
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void BRepFeat_MakeDPrism::Init(const TopoDS_Shape& Sbase,
const TopoDS_Face& Pbase,
const TopoDS_Face& Skface,
const Standard_Real Angle,
const Standard_Integer Mode,
const Standard_Boolean Modify)
{
#ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT();
if (trc) std::cout << "BRepFeat_MakeDPrism::Init" << std::endl;
#endif
mySkface = Skface;
SketchFaceValid();
mySbase = Sbase;
BasisShapeValid();
myPbase = Pbase;
mySlface.Clear();
if(Mode == 0) {
myFuse = Standard_False;
myJustFeat = Standard_False;
}
else if(Mode == 1) {
myFuse = Standard_True;
myJustFeat = Standard_False;
}
else if(Mode == 2) {
myFuse = Standard_True;
myJustFeat = Standard_True;
}
else {
}
myModify = Modify;
myJustGluer = Standard_False;
//-------------- ifv
//mySkface.Nullify();
//-------------- ifv
myShape.Nullify();
myMap.Clear();
myFShape.Nullify();
myLShape.Nullify();
myTopEdges.Clear();
myLatEdges.Clear();
TopExp_Explorer exp;
for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
TopTools_ListOfShape thelist;
myMap.Bind(exp.Current(), thelist);
myMap(exp.Current()).Append(exp.Current());
}
myAngle = Angle;
#ifdef OCCT_DEBUG
if (trc) {
if (myJustFeat) std::cout << " Just Feature" << std::endl;
if (myFuse) std::cout << " Fuse" << std::endl;
if (!myFuse) std::cout << " Cut" << std::endl;
if (!myModify) std::cout << " Modify = 0" << std::endl;
// std::cout <<" Angle = " << myAngle << std::endl;
}
#endif
}
//=======================================================================
//function : Add
//purpose : add sliding faces and edges
//=======================================================================
void BRepFeat_MakeDPrism::Add(const TopoDS_Edge& E,
const TopoDS_Face& F)
{
#ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT();
if (trc) std::cout << "BRepFeat_MakeDPrism::Add(Edge,face)" << std::endl;
#endif
TopExp_Explorer exp;
for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
if (exp.Current().IsSame(F)) {
break;
}
}
if (!exp.More()) {
throw Standard_ConstructionError();
}
for (exp.Init(myPbase,TopAbs_EDGE);exp.More();exp.Next()) {
if (exp.Current().IsSame(E)) {
break;
}
}
if (!exp.More()) {
throw Standard_ConstructionError();
}
if (!mySlface.IsBound(F)) {
TopTools_ListOfShape thelist;
mySlface.Bind(F, thelist);
}
TopTools_ListIteratorOfListOfShape itl(mySlface(F));
for (; itl.More();itl.Next()) {
if (itl.Value().IsSame(E)) {
break;
}
}
if (!itl.More()) {
mySlface(F).Append(E);
}
}
//=======================================================================
//function : Perform
//purpose : feature of Height
//=======================================================================
void BRepFeat_MakeDPrism::Perform(const Standard_Real Height)
{
#ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT();
if (trc) std::cout << "BRepFeat_MakeDPrism::Perform(Height)" << std::endl;
#endif
mySFrom.Nullify();
ShapeFromValid();
mySUntil.Nullify();
ShapeUntilValid();
myGluedF.Clear();
myPerfSelection = BRepFeat_NoSelection;
PerfSelectionValid();
Standard_Real theheight = Height/cos(myAngle);
// myPbase.Orientation(TopAbs_FORWARD);
LocOpe_DPrism theDPrism(myPbase,theheight,myAngle);
const TopoDS_Shape& VraiDPrism = theDPrism.Shape();
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
myGShape = VraiDPrism;
GeneratedShapeValid();
const TopoDS_Shape& Base = theDPrism.FirstShape();
TopExp_Explorer exp(Base, TopAbs_FACE);
TopoDS_Face theBase = TopoDS::Face(exp.Current());
exp.Next();
if(exp.More()) {
NotDone();
myStatusError = BRepFeat_InvFirstShape;
return;
}
// management of gluing faces
GluedFacesValid();
if(!myGluedF.IsEmpty()) { // case gluing
myJustGluer = Standard_True;
theDPrism.Curves(myCurves);
myBCurve = theDPrism.BarycCurve();
GlobalPerform();
}
// if there is no gluing -> call topological operations
if(!myJustGluer) {
if(myFuse == 1) {
BRepAlgoAPI_Fuse f(mySbase, myGShape);
myShape = f.Shape();
UpdateDescendants(f, myShape, Standard_False);
Done();
}
else if(myFuse == 0) {
BRepAlgoAPI_Cut c(mySbase, myGShape);
myShape = c.Shape();
UpdateDescendants(c, myShape, Standard_False);
Done();
}
else {
myShape = myGShape;
Done();
}
}
}
//=======================================================================
//function : Perform
//purpose : feature limited by the shape Until
//=======================================================================
void BRepFeat_MakeDPrism::Perform(const TopoDS_Shape& Until)
{
#ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT();
if (trc) std::cout << "BRepFeat_MakeDPrism::Perform(Until)" << std::endl;
#endif
if (Until.IsNull()) {
throw Standard_ConstructionError();
}
TopExp_Explorer exp(Until, TopAbs_FACE);
if (!exp.More()) {
throw Standard_ConstructionError();
}
// myPbase.Orientation(TopAbs_FORWARD);
myGluedF.Clear();
myPerfSelection = BRepFeat_SelectionU;
PerfSelectionValid();
mySFrom.Nullify();
ShapeFromValid();
mySUntil = Until;
Standard_Boolean Trf = TransformShapeFU(1);
ShapeUntilValid();
Handle(Geom_Curve) C = TestCurve(myPbase);
Standard_Integer sens = SensOfPrism(C, mySUntil);
BRep_Builder bB;
Standard_Real Height =
sens*HeightMax(mySbase, mySkface, mySFrom, mySUntil);
LocOpe_DPrism theDPrism(myPbase,Height,myAngle);
const TopoDS_Shape& VraiDPrism = theDPrism.Shape();
if(!Trf) {
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
myGShape = VraiDPrism;
GeneratedShapeValid();
const TopoDS_Shape& Base = theDPrism.FirstShape();
exp.Init(Base, TopAbs_FACE);
TopoDS_Face theBase = TopoDS::Face(exp.Current());
exp.Next();
if(exp.More()) {
NotDone();
myStatusError = BRepFeat_InvFirstShape;
return;
}
GluedFacesValid();
theDPrism.Curves(myCurves);
myBCurve = theDPrism.BarycCurve();
GlobalPerform();
}
else {
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
Handle(Geom_Curve) C1;
if(sens == -1) {
C1 = C->Reversed();
}
else {
C1 = C;
}
TColGeom_SequenceOfCurve scur;
scur.Clear();
scur.Append(C1);
LocOpe_CSIntersector ASI(mySUntil);
ASI.Perform(scur);
TopAbs_Orientation Or;
if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
if (myFuse == 1) {
Or = ASI.Point(1,1).Orientation();
}
else {
Or = ASI.Point(1,ASI.NbPoints(1)).Orientation();
}
// Standard_Real prm = ASI.Point(1,1).Parameter();
// if(prm < 0) Or = TopAbs::Reverse(Or);
TopoDS_Face FUntil = ASI.Point(1,1).Face();
TopoDS_Shape Comp;
bB.MakeCompound(TopoDS::Compound(Comp));
TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
if (!S.IsNull()) bB.Add(Comp,S);
BRepAlgoAPI_Cut trP(VraiDPrism,Comp);
UpdateDescendants(trP, trP.Shape(), Standard_False);
TopExp_Explorer ex(trP.Shape(), TopAbs_SOLID);
const TopoDS_Shape& Cutsh = ex.Current();
if(myFuse == 1) {
BRepAlgoAPI_Fuse f(mySbase, Cutsh);
myShape = f.Shape();
UpdateDescendants(f, myShape, Standard_False);
Done();
}
else if(myFuse == 0) {
BRepAlgoAPI_Cut c(mySbase, Cutsh);
myShape = c.Shape();
UpdateDescendants(c, myShape, Standard_False);
Done();
}
else {
myShape = Cutsh;
Done();
}
}
}
TopTools_ListIteratorOfListOfShape ited(myNewEdges);
for (; ited.More();ited.Next()) {
const TopoDS_Edge& ledg=TopoDS::Edge(ited.Value());
if (!BRepAlgo::IsValid(ledg)) {
bB.SameRange(ledg, Standard_False);
bB.SameParameter(ledg, Standard_False);
BRepLib::SameParameter(ledg, BRep_Tool::Tolerance(ledg));
}
}
}
//=======================================================================
//function : Perform
//purpose : feature limited by two shapes
//=======================================================================
void BRepFeat_MakeDPrism::Perform(const TopoDS_Shape& From,
const TopoDS_Shape& Until)
{
#ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT();
if (trc) std::cout << "BRepFeat_MakeDPrism::Perform(From,Until)" << std::endl;
#endif
if (From.IsNull() || Until.IsNull()) {
throw Standard_ConstructionError();
}
if (!mySkface.IsNull()) {
if (From.IsSame(mySkface)) {
myJustGluer = Standard_True;
Perform(Until);
if (myJustGluer) return;
}
else if (Until.IsSame(mySkface)) {
myJustGluer = Standard_True;
Perform(From);
if (myJustGluer) return;
}
}
// myPbase.Orientation(TopAbs_FORWARD);
myGluedF.Clear();
myPerfSelection = BRepFeat_SelectionFU;
PerfSelectionValid();
TopExp_Explorer exp(From, TopAbs_FACE);
if (!exp.More()) {
throw Standard_ConstructionError();
}
exp.Init(Until, TopAbs_FACE);
if (!exp.More()) {
throw Standard_ConstructionError();
}
mySFrom = From;
Standard_Boolean Trff = TransformShapeFU(0);
ShapeFromValid();
mySUntil = Until;
Standard_Boolean Trfu = TransformShapeFU(1);
ShapeUntilValid();
if(Trfu != Trff) {
NotDone();
myStatusError = BRepFeat_IncTypes;
return;
}
Handle(Geom_Curve) C = TestCurve(myPbase);
Standard_Integer sens;
if(From.IsSame(Until)) {
sens = 1;
}
else {
sens = SensOfPrism(C, mySUntil);
}
Standard_Real Height =
sens*HeightMax(mySbase, myPbase, mySFrom, mySUntil);
LocOpe_DPrism theDPrism(myPbase, Height, Height, myAngle);
const TopoDS_Shape& VraiDPrism = theDPrism.Shape();
if(!Trff) {
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
// Make systematically dprism
myGShape = VraiDPrism;
GeneratedShapeValid();
// management of gluing faces
// mySbase, myPbase, mySlface, theDPrism, myGluedF);
GluedFacesValid();
theDPrism.Curves(myCurves);
myBCurve = theDPrism.BarycCurve();
// topologic reconstruction
GlobalPerform();
}
else {
// management of descendants
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
Handle(Geom_Curve) C1;
if(sens == -1) {
C1 = C->Reversed();
}
else {
C1 = C;
}
TColGeom_SequenceOfCurve scur;
scur.Clear();
scur.Append(C1);
LocOpe_CSIntersector ASI1(mySUntil);
LocOpe_CSIntersector ASI2(mySFrom);
ASI1.Perform(scur);
ASI2.Perform(scur);
TopAbs_Orientation OrU, OrF;
TopoDS_Face FFrom, FUntil;
//direction of dprism
if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
if (myFuse == 1) {
OrU = ASI1.Point(1,1).Orientation();
}
else {
OrU = ASI1.Point(1,ASI1.NbPoints(1)).Orientation();
}
// Standard_Real prm = ASI1.Point(1,1).Parameter();
// if(prm < 0) OrU = TopAbs::Reverse(OrU);
FUntil = ASI1.Point(1,1).Face();
}
else {
NotDone();
myStatusError = BRepFeat_NoIntersectU;
return;
}
if (ASI2.IsDone() && ASI2.NbPoints(1) >=1) {
OrF = ASI2.Point(1,1).Orientation();
// Standard_Real prm = ASI2.Point(1,1).Parameter();
OrF = TopAbs::Reverse(OrF);
FFrom = ASI2.Point(1,1).Face();
}
else {
NotDone();
myStatusError = BRepFeat_NoIntersectF;
return;
}
TopoDS_Shape Comp;
BRep_Builder B;
B.MakeCompound(TopoDS::Compound(Comp));
TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, OrU);
if (!S.IsNull()) B.Add(Comp,S);
else {
NotDone();
myStatusError = BRepFeat_NullToolU;
return;
}
TopoDS_Solid SS = BRepFeat::Tool(mySFrom, FFrom, OrF);
if (!SS.IsNull()) B.Add(Comp,SS);
else {
NotDone();
myStatusError = BRepFeat_NullToolF;
return;
}
BRepAlgoAPI_Cut trP(VraiDPrism,Comp);
if(myFuse == 1) {
BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
myShape = f.Shape();
UpdateDescendants(f, myShape, Standard_False);
Done();
}
//
else if(myFuse == 0) {
BRepAlgoAPI_Cut c(mySbase, trP.Shape());
myShape = c.Shape();
UpdateDescendants(c, myShape, Standard_False);
Done();
}
else {
myShape = trP.Shape();
Done();
}
}
}
//=======================================================================
//function : Perform
//purpose : feature semi-infinie
//=======================================================================
void BRepFeat_MakeDPrism::PerformUntilEnd()
{
#ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT();
if (trc) std::cout << "BRepFeat_MakeDPrism::PerformUntilEnd()" << std::endl;
#endif
myPerfSelection = BRepFeat_SelectionSh;
PerfSelectionValid();
myGluedF.Clear();
mySUntil.Nullify();
ShapeUntilValid();
mySFrom.Nullify();
ShapeFromValid();
Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
// myPbase.Orientation(TopAbs_FORWARD);
LocOpe_DPrism theDPrism(myPbase, Height, myAngle);
const TopoDS_Shape& VraiDPrism = theDPrism.Shape();
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
myGShape = VraiDPrism;
GeneratedShapeValid();
GluedFacesValid();
theDPrism.Curves(myCurves);
myBCurve = theDPrism.BarycCurve();
GlobalPerform();
}
//=======================================================================
//function : PerformFromEnd
//purpose : feature semiinfinite limited by the shape Until from the other side
//=======================================================================
void BRepFeat_MakeDPrism::PerformFromEnd(const TopoDS_Shape& Until)
{
#ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT();
if (trc) std::cout << "BRepFeat_MakeDPrism::PerformFromEnd(From,Until)" << std::endl;
#endif
if (Until.IsNull()) {
throw Standard_ConstructionError();
}
if (!mySkface.IsNull() && Until.IsSame(mySkface)) {
PerformUntilEnd();
return;
}
TopExp_Explorer exp;
exp.Init(Until, TopAbs_FACE);
if (!exp.More()) {
throw Standard_ConstructionError();
}
// myPbase.Orientation(TopAbs_FORWARD);
myPerfSelection = BRepFeat_SelectionShU;
PerfSelectionValid();
mySFrom.Nullify();
ShapeFromValid();
mySUntil = Until;
Standard_Boolean Trf = TransformShapeFU(1);
ShapeUntilValid();
Handle(Geom_Curve) C = TestCurve(myPbase);
Standard_Integer sens = SensOfPrism(C, mySUntil);
Standard_Real Height =
sens*HeightMax(mySbase, mySkface, mySFrom, mySUntil);
LocOpe_DPrism theDPrism(myPbase, Height, Height, myAngle);
const TopoDS_Shape& VraiDPrism = theDPrism.Shape();
if(VraiDPrism.IsNull()) {
NotDone();
myStatusError = BRepFeat_NullRealTool;
return;
}
if(!Trf) { // case finite face
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
myGShape = VraiDPrism;
GeneratedShapeValid();
myGluedF.Clear();
GluedFacesValid();
theDPrism.Curves(myCurves);
myBCurve = theDPrism.BarycCurve();
GlobalPerform();
}
else { // case support
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
Handle(Geom_Curve) C2;
if(sens == -1) {
C2 = C->Reversed();
}
else {
C2 = C;
}
TColGeom_SequenceOfCurve scur;
scur.Clear();
scur.Append(C2);
LocOpe_CSIntersector ASI1(mySUntil);
LocOpe_CSIntersector ASI2(mySbase);
ASI1.Perform(scur);
ASI2.Perform(scur);
TopAbs_Orientation OrU = TopAbs_FORWARD, OrF = TopAbs_FORWARD;
TopoDS_Face FUntil, FFrom;
if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
OrU = ASI1.Point(1,1).Orientation();
Standard_Real prm = ASI1.Point(1,1).Parameter();
if(prm < 0) OrU = TopAbs::Reverse(OrU);
FUntil = ASI1.Point(1,1).Face();
}
if (ASI2.IsDone() && ASI2.NbPoints(1) >=1) {
Standard_Integer jj = ASI2.NbPoints(1);
Standard_Real prm = ASI2.Point(1,1).Parameter();
FFrom = ASI2.Point(1, 1).Face();
OrF = ASI2.Point(1,1).Orientation();
OrF = TopAbs::Reverse(OrF);
for(Standard_Integer iii = 1; iii <= jj; iii++) {
if(ASI2.Point(1,iii).Parameter() < prm) {
prm = ASI2.Point(1,iii).Parameter();
FFrom = ASI2.Point(1, iii).Face();
OrF = ASI2.Point(1,iii).Orientation();
OrF = TopAbs::Reverse(OrF);
}
}
Handle(Geom_Surface) S = BRep_Tool::Surface(FFrom);
if (S->DynamicType() ==
STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
S = Handle(Geom_RectangularTrimmedSurface)::
DownCast(S)->BasisSurface();
}
BRepLib_MakeFace fac(S, Precision::Confusion());
mySFrom = fac.Face();
Trf = TransformShapeFU(0);
// FFrom = TopoDS::Face(mySFrom);
}
TopoDS_Shape Comp;
BRep_Builder B;
B.MakeCompound(TopoDS::Compound(Comp));
TopoDS_Solid Sol = BRepFeat::Tool(mySUntil, FUntil, OrU);
if (!Sol.IsNull()) B.Add(Comp,Sol);
else {
NotDone();
myStatusError = BRepFeat_NullToolU;
return;
}
TopoDS_Solid Sol1 = BRepFeat::Tool(mySFrom, FFrom, OrF);
if (!Sol1.IsNull()) B.Add(Comp,Sol1);
else {
NotDone();
myStatusError = BRepFeat_NullToolF;
return;
}
BRepAlgoAPI_Cut trP(VraiDPrism,Comp);
if(myFuse == 1) {
BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
myShape = f.Shape();
UpdateDescendants(f, myShape, Standard_False);
Done();
}
else if(myFuse == 0) {
BRepAlgoAPI_Cut c(mySbase, trP.Shape());
myShape = c.Shape();
UpdateDescendants(c, myShape, Standard_False);
Done();
}
else {
myShape = trP.Shape();
Done();
}
}
}
//=======================================================================
//function : PerformThruAll
//purpose : feature throughout the entire initial shape
//=======================================================================
void BRepFeat_MakeDPrism::PerformThruAll()
{
#ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT();
if (trc) std::cout << "BRepFeat_MakeDPrism::PerformThruAll()" << std::endl;
#endif
mySUntil.Nullify();
ShapeUntilValid();
mySFrom.Nullify();
ShapeFromValid();
if(myFuse == 0) {
myPerfSelection = BRepFeat_NoSelection;
}
else {
myPerfSelection = BRepFeat_SelectionSh;
}
PerfSelectionValid();
// myPbase.Orientation(TopAbs_FORWARD);
myGluedF.Clear();
GluedFacesValid();
Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
LocOpe_DPrism theDPrism(myPbase, Height, Height, myAngle);
const TopoDS_Shape& VraiDPrism = theDPrism.Shape();
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
myGShape = VraiDPrism;
GeneratedShapeValid();
if(myFuse == 0) {
BRepAlgoAPI_Cut c(mySbase, myGShape);
if (c.IsDone()) {
myShape = c.Shape();
UpdateDescendants(c, myShape, Standard_False);
Done();
}
}
else {
theDPrism.Curves(myCurves);
myBCurve = theDPrism.BarycCurve();
GlobalPerform();
}
}
//=======================================================================
//function : PerformUntilHeight
//purpose : feature until the shape is of the given height
//=======================================================================
void BRepFeat_MakeDPrism::PerformUntilHeight(const TopoDS_Shape& Until,
const Standard_Real Height)
{
#ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT();
if (trc) std::cout << "BRepFeat_MakeDPrism::PerformUntilHeight(Until,Height)" << std::endl;
#endif
if (Until.IsNull()) {
Perform(Height);
}
if(Height == 0) {
Perform(Until);
}
TopExp_Explorer exp(Until, TopAbs_FACE);
if (!exp.More()) {
throw Standard_ConstructionError();
}
// myPbase.Orientation(TopAbs_FORWARD);
myGluedF.Clear();
myPerfSelection = BRepFeat_NoSelection;
PerfSelectionValid();
mySFrom.Nullify();
ShapeFromValid();
mySUntil = Until;
Standard_Boolean Trf = TransformShapeFU(1);
ShapeUntilValid();
Handle(Geom_Curve) C = TestCurve(myPbase);
Standard_Integer sens = SensOfPrism(C, mySUntil);
LocOpe_DPrism theDPrism(myPbase,sens*Height,myAngle);
const TopoDS_Shape& VraiDPrism = theDPrism.Shape();
if(!Trf) { // case face finished
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
myGShape = VraiDPrism;
GeneratedShapeValid();
const TopoDS_Shape& Base = theDPrism.FirstShape();
exp.Init(Base, TopAbs_FACE);
TopoDS_Face theBase = TopoDS::Face(exp.Current());
exp.Next();
if(exp.More()) {
NotDone();
myStatusError = BRepFeat_InvFirstShape;
return;
}
GluedFacesValid();
theDPrism.Curves(myCurves);
myBCurve = theDPrism.BarycCurve();
GlobalPerform();
}
else { // case support
MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
Handle(Geom_Curve) C1;
if(sens == -1) {
C1 = C->Reversed();
}
else {
C1 = C;
}
TColGeom_SequenceOfCurve scur;
scur.Clear();
scur.Append(C1);
LocOpe_CSIntersector ASI(mySUntil);
ASI.Perform(scur);
TopAbs_Orientation Or;
if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
if (myFuse == 1) {
Or = ASI.Point(1,1).Orientation();
}
else {
Or = ASI.Point(1,ASI.NbPoints(1)).Orientation();
}
// Standard_Real prm = ASI.Point(1,1).Parameter();
// if(prm < 0) Or = TopAbs::Reverse(Or);
TopoDS_Face FUntil = ASI.Point(1,1).Face();
TopoDS_Shape Comp;
BRep_Builder B;
B.MakeCompound(TopoDS::Compound(Comp));
TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
if (!S.IsNull()) B.Add(Comp,S);
BRepAlgoAPI_Cut trP(VraiDPrism,Comp);
if(myFuse == 1) {
BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
myShape = f.Shape();
UpdateDescendants(f, myShape, Standard_False);
Done();
}
else if(myFuse == 0) {
BRepAlgoAPI_Cut c(mySbase, trP.Shape());
myShape = c.Shape();
UpdateDescendants(c, myShape, Standard_False);
Done();
}
else {
myShape = trP.Shape();
Done();
}
}
}
}
//=======================================================================
//function : Curves
//purpose : curves parallel to the axis of the prism
//=======================================================================
void BRepFeat_MakeDPrism::Curves(TColGeom_SequenceOfCurve& scur)
{
scur = myCurves;
}
//============================================================================
// function : BRepFeat_BossEgdes
// purpose: Determination of TopEdges and LatEdges.
// sig = 1 -> TopEdges = FirstShape of the DPrism
// sig = 2 -> TOpEdges = LastShape of the DPrism
//============================================================================
void BRepFeat_MakeDPrism::BossEdges (const Standard_Integer signature)
{
#ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT();
if (trc) std::cout << "BRepFeat_MakeDPrism::BossEdges (integer)" << std::endl;
#endif
TopTools_ListOfShape theLastShape;
theLastShape.Clear();
if (signature == 1 || signature == -1) {
theLastShape = FirstShape();
}
else if (signature == 2 || signature == -2) {
theLastShape = LastShape();
}
else {
return;
}
// Edges Top
TopTools_ListIteratorOfListOfShape itLS;
TopExp_Explorer ExpE;
for (itLS.Initialize(theLastShape);itLS.More();itLS.Next()) {
const TopoDS_Face& FF = TopoDS::Face(itLS.Value());
for (ExpE.Init(FF,TopAbs_EDGE);ExpE.More();ExpE.Next()) {
const TopoDS_Edge& EE = TopoDS::Edge(ExpE.Current());
myTopEdges.Append(EE);
}
}
// Edges Bottom
if (signature < 0) {
// Attention check if TgtEdges is important
myLatEdges = NewEdges();
}
else if (signature > 0) {
if ( !myShape.IsNull() ) {
TopTools_MapOfShape MapE;
Standard_Boolean Found;
TopExp_Explorer ExpF;
for (ExpF.Init(myShape,TopAbs_FACE);ExpF.More();ExpF.Next()) {
Found = Standard_False;
const TopoDS_Face& FF = TopoDS::Face(ExpF.Current());
for (itLS.Initialize(theLastShape);itLS.More();itLS.Next()) {
const TopoDS_Face& TopFace = TopoDS::Face(itLS.Value());
if (!FF.IsSame(TopFace)) {
for (ExpE.Init(FF,TopAbs_EDGE);ExpE.More() && !Found ;ExpE.Next()) {
const TopoDS_Edge& E1 = TopoDS::Edge(ExpE.Current());
TopoDS_Vertex V1,V2;
TopExp::Vertices (E1,V1,V2);
TopTools_ListIteratorOfListOfShape it(myTopEdges);
for (;it.More() && !Found ; it.Next()) {
TopoDS_Edge E2 = TopoDS::Edge(it.Value());
TopoDS_Vertex VT1,VT2;
TopExp::Vertices (E2,VT1,VT2);
if (V1.IsSame(VT1) || V1.IsSame(VT2) || V2.IsSame(VT1) || V2.IsSame(VT2)) {
Found = Standard_True;
TopExp_Explorer ExpE2;
for (ExpE2.Init(FF,TopAbs_EDGE);ExpE2.More();ExpE2.Next()) {
const TopoDS_Edge& E3 = TopoDS::Edge(ExpE2.Current());
if (MapE.Contains(E3)) {
MapE.Remove(E3); }
else {
MapE.Add(E3);}
}
}
}
}
}
}
}
TopTools_ListIteratorOfListOfShape it(myTopEdges);
for (;it.More() ; it.Next()) {
if (MapE.Contains(it.Value())) {MapE.Remove(it.Value()); }
}
TopTools_MapIteratorOfMapOfShape itMap;
for (itMap.Initialize(MapE);itMap.More();itMap.Next()) {
if (!BRep_Tool::Degenerated(TopoDS::Edge(itMap.Key())))
myLatEdges.Append(itMap.Key());
}
}
}
}
//============================================================================
// function : BRepFeat_TopEgdes
// Purpose: Returns the list of TopoDS Edges of the top of the boss
//============================================================================
const TopTools_ListOfShape& BRepFeat_MakeDPrism::TopEdges ()
{
return myTopEdges;
}
//============================================================================
// function : BRepFeat_LatEgdes
// Purpose: Returns the list of TopoDS Edges of the top of the boss
//============================================================================
const TopTools_ListOfShape& BRepFeat_MakeDPrism::LatEdges ()
{
return myLatEdges;
}
//=======================================================================
//function : BarycCurve
//purpose : passe par le centre de masses de la primitive
//=======================================================================
Handle(Geom_Curve) BRepFeat_MakeDPrism::BarycCurve()
{
return myBCurve;
}
//=======================================================================
//function : HeightMax
//purpose : Calculate the height of the prism following the parameters of the bounding box
//=======================================================================
static Standard_Real HeightMax(const TopoDS_Shape& theSbase, // shape initial
const TopoDS_Face& theSkface, // face de sketch
const TopoDS_Shape& theSFrom, // shape from
const TopoDS_Shape& theSUntil) // shape until
{
Bnd_Box Box;
BRepBndLib::Add(theSbase,Box);
BRepBndLib::Add(theSkface,Box);
if(!theSFrom.IsNull()) {
BRepBndLib::Add(theSFrom,Box);
}
if(!theSUntil.IsNull()) {
BRepBndLib::Add(theSUntil,Box);
}
Standard_Real c[6];
Box.Get(c[0],c[2],c[4],c[1],c[3],c[5]);
// Standard_Real parmin=c[0], parmax = c[0];
// for(Standard_Integer i = 0 ; i < 6; i++) {
// if(c[i] > parmax) parmax = c[i];
// if(c[i] < parmin ) parmin = c[i];
// }
// Standard_Real Height = abs(2.*(parmax - parmin));
// return(2.*Height);
//#ifndef OCCT_DEBUG
Standard_Real par = Max( Max( fabs(c[1] - c[0]), fabs(c[3] - c[2]) ), fabs(c[5] - c[4]) );
//#else
// Standard_Real par = Max( Max( abs(c[1] - c[0]), abs(c[3] - c[2]) ), abs(c[5] - c[4]) );
//#endif
#ifdef OCCT_DEBUG
std::cout << "Height = > " << par << std::endl;
#endif
return par;
}
//=======================================================================
//function : SensOfPrism
//purpose : determine the direction of prism generation
//=======================================================================
Standard_Integer SensOfPrism(const Handle(Geom_Curve)& C,
const TopoDS_Shape& Until)
{
LocOpe_CSIntersector ASI1(Until);
TColGeom_SequenceOfCurve scur;
scur.Append(C);
ASI1.Perform(scur);
Standard_Integer sens = 1;
if(ASI1.IsDone() && ASI1.NbPoints(1) >= 1) {
Standard_Integer nb = ASI1.NbPoints(1);
Standard_Real prm1 = ASI1.Point(1, 1).Parameter();
Standard_Real prm2 = ASI1.Point(1, nb).Parameter();
if(prm1 < 0. && prm2 < 0.) {
sens = -1;
}
}
else if(BRepFeat::ParametricBarycenter(Until,C) < 0) {
sens = -1;
}
else {}
return sens;
}
//=======================================================================
//function : MajMap
//purpose :
//=======================================================================
static void MajMap(const TopoDS_Shape& theB,
const LocOpe_DPrism& theP,
TopTools_DataMapOfShapeListOfShape& theMap, // myMap
TopoDS_Shape& theFShape, // myFShape
TopoDS_Shape& theLShape) // myLShape
{
TopExp_Explorer exp;
if(!theP.FirstShape().IsNull()) {
exp.Init(theP.FirstShape(),TopAbs_WIRE);
if (exp.More()) {
theFShape = exp.Current();
TopTools_ListOfShape thelist;
theMap.Bind(theFShape, thelist);
for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
theMap(theFShape).Append(exp.Current());
}
}
}
if(!theP.LastShape().IsNull()) {
exp.Init(theP.LastShape(),TopAbs_WIRE);
if (exp.More()) {
theLShape = exp.Current();
TopTools_ListOfShape thelist1;
theMap.Bind(theLShape, thelist1);
for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
theMap(theLShape).Append(exp.Current());
}
}
}
for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
if (!theMap.IsBound(exp.Current())) {
const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
TopTools_ListOfShape thelist2;
theMap.Bind(edg, thelist2);
theMap(edg) = theP.Shapes(edg);
}
}
}
//=======================================================================
//function : MajMap
//purpose :
//=======================================================================
static Handle(Geom_Curve) TestCurve(const TopoDS_Face& Base)
{
gp_Pnt bar(0., 0., 0.);
TColgp_SequenceOfPnt spt;
LocOpe::SampleEdges(Base,spt);
for (Standard_Integer jj=1;jj<=spt.Length(); jj++) {
const gp_Pnt& pvt = spt(jj);
bar.ChangeCoord() += pvt.XYZ();
}
bar.ChangeCoord().Divide(spt.Length());
Handle(Geom_Surface) s = BRep_Tool::Surface(Base);
if (s->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
s = Handle(Geom_RectangularTrimmedSurface)::
DownCast(s)->BasisSurface();
}
Handle (Geom_Plane) P = Handle(Geom_Plane)::DownCast(s);
if(P.IsNull()) {
Handle(Geom_Curve) toto;
return toto;
}
gp_Pln pp = P->Pln();
gp_Dir Normale(pp.Position().XDirection()^pp.Position().YDirection());
gp_Ax1 theAx(bar, Normale);
Handle(Geom_Line) theLin = new Geom_Line(theAx);
return theLin;
}