1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-06-15 11:44:07 +03:00
occt/src/LocOpe/LocOpe_SplitDrafts.cxx
dpasukhi 1103eb60af 0033370: Foundation Classes - Moving into STL and Boost functionality
NCollection containers update:
  - NCollection_Array1 - updated functionality
  - NCollection_Array2 - NCollection_Array1 as a wrapper for 2array
  - NCollection_Vector -> NCollection_DynamicArray was renamed and reworked.
TCollection:
  - Use static empty string to avoid allocations on empty string
 NCollection allocators update:
  - NCollection_Allocator - allocator that used Standard::Allocate
  - NCollection_OccAllocator - allocator-wrapper that used OCC BaseAllocator objects
  - NCollection_IncAllocator - rework to increase performance
Standard:
  - Rework functionality to use different allocation libs
  - Implement basic of new way to wrap allocations tools
  - Define 4 ways to allocation (defines in configure stage)
 Additional changes:
  - Hash function uses std::hash functionality
   - size_t as a hash value
  - New HashUtils with Murmur and FVN hash algo for x32 and x64
  - Deprecated _0.cxx and .gxx DE classes reorganized
  - Create own utility for std memory
  - Update Standard_Transient to be more platform-independent
 Math TK changes:
  - math_Vector -> match_BaseVector<>
    - Buffer decreased to cash 32 elements instead of 512
2023-12-04 13:37:09 +00:00

1780 lines
47 KiB
C++

// Created on: 1996-10-02
// Created by: Jacques GOUSSARD
// 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 <LocOpe_SplitDrafts.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepGProp.hxx>
#include <BRepTools_Substitution.hxx>
#include <Extrema_ExtPC.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_Line.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomFill_Pipe.hxx>
#include <GeomInt_IntSS.hxx>
#include <gp.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <GProp_GProps.hxx>
#include <IntAna_QuadQuadGeo.hxx>
#include <IntCurveSurface_HInter.hxx>
#include <IntCurveSurface_IntersectionPoint.hxx>
#include <IntCurveSurface_IntersectionSegment.hxx>
#include <LocOpe_BuildShape.hxx>
#include <LocOpe_Spliter.hxx>
#include <LocOpe_SplitShape.hxx>
#include <LocOpe_WiresOnShape.hxx>
#include <Precision.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_NullObject.hxx>
#include <StdFail_NotDone.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_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
static Standard_Boolean NewPlane(const TopoDS_Face&,
const gp_Dir&,
const gp_Pln&,
const Standard_Real,
gp_Pln&,
gp_Ax1&,
const Standard_Boolean);
static void MakeFace(TopoDS_Face&,
TopTools_ListOfShape&);
static TopoDS_Edge NewEdge(const TopoDS_Edge&,
const TopoDS_Face&,
const Handle(Geom_Surface)&,
const TopoDS_Vertex&,
const TopoDS_Vertex&);
static Standard_Boolean Contains(const TopTools_ListOfShape&,
const TopoDS_Shape&);
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void LocOpe_SplitDrafts::Init(const TopoDS_Shape& S)
{
myShape = S;
myResult.Nullify();
myMap.Clear();
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void LocOpe_SplitDrafts::Perform(const TopoDS_Face& F,
const TopoDS_Wire& W,
const gp_Dir& Extr,
const gp_Pln& NPl,
const Standard_Real Angle)
{
Perform(F,W,Extr,NPl,Angle,Extr,NPl,Angle,Standard_True,Standard_False);
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void LocOpe_SplitDrafts::Perform(const TopoDS_Face& F,
const TopoDS_Wire& W,
const gp_Dir& Extrg,
const gp_Pln& NPlg,
const Standard_Real Angleg,
const gp_Dir& Extrd,
const gp_Pln& NPld,
const Standard_Real Angled,
const Standard_Boolean ModLeft,
const Standard_Boolean ModRight)
{
Standard_Integer j ;
myResult.Nullify();
myMap.Clear();
if (myShape.IsNull() || F.IsNull() || W.IsNull()) {
throw Standard_NullObject();
}
if (!ModLeft && !ModRight) {
throw Standard_ConstructionError();
}
TopAbs_Orientation OriF = TopAbs_FORWARD;
Standard_Boolean FinS = Standard_False;
TopExp_Explorer exp,exp2;
for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
const TopoDS_Shape& fac = exp.Current();
TopTools_ListOfShape thelist;
myMap.Bind(fac, thelist);
if (fac.IsSame(F)) {
OriF = fac.Orientation();
FinS = Standard_True;
}
}
if (!FinS) {
std::cout << "LocOpe_SplitDrafts:!Fins throw Standard_ConstructionError()" << std::endl;
throw Standard_ConstructionError();
}
gp_Pln NewPlg,NewPld;
gp_Ax1 NormalFg,NormalFd;
TopoDS_Shape aLocalFace = F.Oriented(OriF);
if (!NewPlane(TopoDS::Face(aLocalFace),
Extrg,NPlg,Angleg,NewPlg,NormalFg,ModLeft) ||
!NewPlane(TopoDS::Face(aLocalFace),
Extrd,NPld,Angled,NewPld,NormalFd,ModRight)) {
// if (!NewPlane(TopoDS::Face(F.Oriented(OriF)),
// Extrg,NPlg,Angleg,NewPlg,NormalFg,ModLeft) ||
// !NewPlane(TopoDS::Face(F.Oriented(OriF)),
// Extrd,NPld,Angled,NewPld,NormalFd,ModRight)) {
return;
}
TopTools_ListIteratorOfListOfShape itl;
BRep_Builder B;
Handle(Geom_Surface) NewSg = new Geom_Plane(NewPlg);
Handle(Geom_Surface) NewSd = new Geom_Plane(NewPld);
Handle(Geom_Line) theLinePipe = new Geom_Line(NormalFg); // ou NormalFd
GeomInt_IntSS i2s(NewSg,NewSd,Precision::Confusion());
TopTools_MapOfShape theMap;
Handle(GeomAdaptor_Curve) HAC = new GeomAdaptor_Curve;
Handle(GeomAdaptor_Surface) HAS = new GeomAdaptor_Surface;
IntCurveSurface_HInter intcs;
TopoDS_Wire theW = W;
if (i2s.IsDone() && i2s.NbLines() > 0) {
// on split le wire" << std::endl;
GeomFill_Pipe thePipe;
thePipe.GenerateParticularCase(Standard_True);
thePipe.Init(theLinePipe,i2s.Line(1));
thePipe.Perform(Standard_True);
if (!thePipe.IsDone())
throw Standard_ConstructionError("GeomFill_Pipe : Cannot make a surface");
Handle(Geom_Surface) Spl = thePipe.Surface();
HAS->Load(Spl);
LocOpe_SplitShape splw(W);
for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
if (theMap.Add(edg)) {
TopLoc_Location Loc;
Standard_Real f,l;
Handle(Geom_Curve) C = BRep_Tool::Curve(edg,f,l);
HAC->Load(C);
intcs.Perform(HAC,HAS);
if (!intcs.IsDone()) {
continue; // voir ce qu`on peut faire de mieux
}
if (intcs.NbSegments() >= 2) {
continue; // Not yet implemented...and probably never"
}
if (intcs.NbSegments() == 1) {
const IntCurveSurface_IntersectionPoint& P1 =
intcs.Segment(1).FirstPoint();
const IntCurveSurface_IntersectionPoint& P2 =
intcs.Segment(1).SecondPoint();
const gp_Pnt& pf = P1.Pnt();
const gp_Pnt& pl = P2.Pnt();
TopoDS_Vertex Vf,Vl;
TopExp::Vertices(edg,Vf,Vl);
gp_Pnt Pf = BRep_Tool::Pnt(Vf);
gp_Pnt Pl = BRep_Tool::Pnt(Vl);
Standard_Real Tolf = BRep_Tool::Tolerance(Vf);
Standard_Real Toll = BRep_Tool::Tolerance(Vl);
Tolf *= Tolf;
Toll *= Toll;
Standard_Real dff = pf.SquareDistance(Pf);
Standard_Real dfl = pf.SquareDistance(Pl);
Standard_Real dlf = pl.SquareDistance(Pf);
Standard_Real dll = pl.SquareDistance(Pl);
if ((dff <= Tolf && dll <= Toll) ||
(dlf <= Tolf && dfl <= Toll)) {
continue;
}
else {
// on segmente edg en pf et pl
TopoDS_Vertex Vnewf,Vnewl;
B.MakeVertex(Vnewf,pf,Precision::Confusion());
B.MakeVertex(Vnewl,pl,Precision::Confusion());
if (P1.W() >= f && P1.W() <= l &&
P2.W() >= f && P2.W() <= l) {
splw.Add(Vnewf,P1.W(),edg);
splw.Add(Vnewl,P2.W(),edg);
}
else {
continue;
}
}
}
else if (intcs.NbPoints() != 0) {
TopoDS_Vertex Vf,Vl;
TopExp::Vertices(edg,Vf,Vl);
gp_Pnt Pf = BRep_Tool::Pnt(Vf);
gp_Pnt Pl = BRep_Tool::Pnt(Vl);
Standard_Real Tolf = BRep_Tool::Tolerance(Vf);
Standard_Real Toll = BRep_Tool::Tolerance(Vl);
Tolf *= Tolf;
Toll *= Toll;
for (Standard_Integer i = 1; i <= intcs.NbPoints(); i++) {
const IntCurveSurface_IntersectionPoint& Pi = intcs.Point(i);
const gp_Pnt& pi = Pi.Pnt();
Standard_Real dif = pi.SquareDistance(Pf);
Standard_Real dil = pi.SquareDistance(Pl);
if (dif <= Tolf) {
}
else if (dil <= Toll) {
}
else {
if (Pi.W() >= f && Pi.W() <= l) {
TopoDS_Vertex Vnew;
B.MakeVertex(Vnew,pi,Precision::Confusion());
splw.Add(Vnew,Pi.W(),edg);
}
}
}
}
}
}
const TopTools_ListOfShape& lres = splw.DescendantShapes(W);
if (lres.Extent() != 1) {
return;
}
if (!W.IsSame(lres.First())) {
theW.Nullify();
theW = TopoDS::Wire(lres.First());
}
for (exp.ReInit(); exp.More(); exp.Next()) {
if (!myMap.IsBound(exp.Current())) {
TopTools_ListOfShape thelist1;
myMap.Bind(exp.Current(), thelist1);
for (itl.Initialize(splw.DescendantShapes(exp.Current()));
itl.More(); itl.Next()) {
myMap(exp.Current()).Append(itl.Value());
}
for (exp2.Init(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next()) {
if (!myMap.IsBound(exp2.Current())) {
TopTools_ListOfShape thelist2;
myMap.Bind(exp2.Current(), thelist2);
myMap(exp2.Current()).Append(exp2.Current());
}
}
}
}
}
else {
for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
if (!myMap.IsBound(exp.Current())) {
TopTools_ListOfShape thelist3;
myMap.Bind(exp.Current(), thelist3);
myMap(exp.Current()).Append(exp.Current());
for (exp2.Init(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next()) {
if (!myMap.IsBound(exp2.Current())) {
TopTools_ListOfShape thelist4;
myMap.Bind(exp2.Current(), thelist4);
myMap(exp2.Current()).Append(exp2.Current());
}
}
}
}
}
// On split la face par le wire
Handle(LocOpe_WiresOnShape) WonS = new LocOpe_WiresOnShape(myShape);
LocOpe_Spliter Spls(myShape);
WonS->Bind(theW,F);
// JAG Le code suivant marchera apres integration de thick0
// LocOpe_FindEdges fined(W,F);
// for (fined.InitIterator(); fined.More(); fined.Next()) {
// WonS->Bind(fined.EdgeFrom(),fined.EdgeTo());
// }
Spls.Perform(WonS);
if (!Spls.IsDone()) {
return;
}
TopoDS_Shape Res = Spls.ResultingShape();
const TopTools_ListOfShape& theLeft = Spls.DirectLeft();
// Descendants
for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
const TopoDS_Shape& fac = exp.Current();
for (itl.Initialize(Spls.DescendantShapes(fac)); itl.More(); itl.Next()) {
myMap(fac).Append(itl.Value());
}
}
TopTools_DataMapOfShapeShape MapW;
for (exp.Init(theW,TopAbs_EDGE); exp.More(); exp.Next()) {
if (!MapW.IsBound(exp.Current())) {
MapW.Bind(exp.Current(),TopoDS_Shape());
for (exp2.Init(exp.Current(),TopAbs_VERTEX); exp2.More(); exp2.Next()) {
if (!MapW.IsBound(exp2.Current())) {
MapW.Bind(exp2.Current(),TopoDS_Shape());
}
}
}
}
TopTools_IndexedDataMapOfShapeListOfShape theMapEF;
TopExp::MapShapesAndAncestors(Res,TopAbs_EDGE,TopAbs_FACE,theMapEF);
// On stocke les geometries potentiellement generees par les edges
TopTools_IndexedDataMapOfShapeShape MapEV; // genere
TopTools_DataMapOfShapeListOfShape MapSg,MapSd; // image a gauche et a droite
Standard_Integer Nbedges,index;
for (itl.Initialize(myMap(F)); itl.More(); itl.Next()) {
const TopoDS_Shape& fac = TopoDS::Face(itl.Value());
for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) {
const TopoDS_Shape& edg = exp.Current();
if (MapEV.FindIndex(edg) != 0) {
continue;
}
if (MapW.IsBound(edg)) { // edge du wire initial
TopLoc_Location Loc;
Standard_Real f,l;
Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(edg),Loc,f,l);
if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
}
C = Handle(Geom_Curve)::
DownCast(C->Transformed(Loc.Transformation()));
GeomFill_Pipe thePipe;
thePipe.GenerateParticularCase(Standard_True);
thePipe.Init(theLinePipe,C);
thePipe.Perform(Standard_True);
if (!thePipe.IsDone())
throw Standard_ConstructionError("GeomFill_Pipe : Cannot make a surface");
Handle(Geom_Surface) thePS = thePipe.Surface();
if (thePS->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
thePS = Handle(Geom_RectangularTrimmedSurface)::DownCast(thePS)
->BasisSurface();
}
TopoDS_Face NewFace;
B.MakeFace(NewFace,thePS,Precision::Confusion());
MapEV.Add(edg,NewFace);
}
else { // on recupere la face.
index = theMapEF.FindIndex(edg);
if (theMapEF(index).Extent() != 2) {
return; // NotDone
}
TopoDS_Face theFace;
if (theMapEF(index).First().IsSame(fac)) {
MapEV.Add(edg,theMapEF(index).Last());
}
else {
MapEV.Add(edg,theMapEF(index).First());
}
}
}
}
TopTools_DataMapOfShapeShape MapSonS;
Nbedges = MapEV.Extent();
for (index = 1; index <= Nbedges; index++) {
for (exp.Init(MapEV.FindKey(index),TopAbs_VERTEX);
exp.More(); exp.Next()) {
const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
if (MapEV.FindIndex(vtx)!= 0) {
continue;
}
// Localisation du vertex :
// - entre 2 edges d`origine : on recupere l`edge qui n`est
// pas dans F
// - entre 2 edges du wire : droite
// - mixte : intersection de surfaces
for ( j = 1; j<=Nbedges; j++) {
if (j == index) {
continue;
}
for (exp2.Init(MapEV.FindKey(j),TopAbs_VERTEX);
exp2.More(); exp2.Next()) {
const TopoDS_Shape& vtx2 = exp2.Current();
if (vtx2.IsSame(vtx)) {
break;
}
}
if (exp2.More()) {
break;
}
}
Standard_Integer Choice = 0;
const TopoDS_Shape& edg1 = MapEV.FindKey(index);
TopoDS_Shape edg2;
if (j <= Nbedges) {
edg2 = MapEV.FindKey(j);
}
else {
edg2 = edg1;
}
if (MapW.IsBound(edg1)) {
if (j>Nbedges) { // doit correspondre a edge ferme
Choice = 2; // droite
}
else if (MapW.IsBound(MapEV.FindKey(j))) {
Choice = 2; // droite
}
else {
Choice = 3; // mixte
}
}
else {
if (j>Nbedges) { // doit correspondre a edge ferme
Choice = 1; // edge a retrouver
}
else if (!MapW.IsBound(MapEV.FindKey(j))) {
Choice = 1; // edge a retrouver
}
else {
Choice = 3; // mixte
}
}
Handle(Geom_Curve) Newc;
Handle(Geom2d_Curve) newCs1,newCs2;
Standard_Real knownp=0;
TopoDS_Edge Ebind;
switch (Choice) {
case 1:
{
for (exp2.Init(Res,TopAbs_EDGE); exp2.More(); exp2.Next()) {
if (exp2.Current().IsSame(edg1) || exp2.Current().IsSame(edg2)) {
continue;
}
// for (TopExp_Explorer exp3(exp2.Current().Oriented(TopAbs_FORWARD),
TopExp_Explorer exp3(exp2.Current().Oriented(TopAbs_FORWARD),
TopAbs_VERTEX) ;
for ( ; exp3.More(); exp3.Next()) {
if (exp3.Current().IsSame(vtx)) {
break;
}
}
if (exp3.More()) {
break;
}
}
if (exp2.More()) {
Standard_Real f,l;
TopLoc_Location Loc;
Newc = BRep_Tool::Curve(TopoDS::Edge(exp2.Current()),Loc,f,l);
Newc = Handle(Geom_Curve)::DownCast
(Newc->Transformed(Loc.Transformation()));
Ebind = TopoDS::Edge(exp2.Current());
knownp = BRep_Tool::Parameter(vtx,Ebind);
}
else { // droite ??? il vaudrait mieux sortir
return;
// gp_Lin theLine(NormalFg);
// theLine.Translate(NormalF.Location(),BRep_Tool::Pnt(vtx));
// Newc = new Geom_Line(theLine);
// knownp = 0.;
}
}
break;
case 2:
{
gp_Lin theLine(NormalFg);
theLine.Translate(NormalFg.Location(),BRep_Tool::Pnt(vtx));
Newc = new Geom_Line(theLine);
knownp = 0.;
}
break;
case 3:
{
const TopoDS_Face& F1 = TopoDS::Face(MapEV.FindFromKey(edg1));
const TopoDS_Face& F2 = TopoDS::Face(MapEV.FindFromKey(edg2));
Handle(Geom_Surface) S1 = BRep_Tool::Surface(F1);
Handle(Geom_Surface) S2 = BRep_Tool::Surface(F2);
Standard_Boolean AppS1 = Standard_False;
Standard_Boolean AppS2 = Standard_False;
if (S1->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
AppS1 = Standard_True;
}
if (S2->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
AppS2 = Standard_True;
}
i2s.Perform(S1,S2,Precision::Confusion(),Standard_True,AppS1,AppS2);
if (!i2s.IsDone() || i2s.NbLines() <= 0) {
return;
}
Standard_Real pmin=0, Dist2, Dist2Min, Glob2Min = RealLast();
GeomAdaptor_Curve TheCurve;
Standard_Integer i,imin,k;
gp_Pnt pv = BRep_Tool::Pnt(vtx);
imin = 0;
for (i=1; i<= i2s.NbLines(); i++) {
TheCurve.Load(i2s.Line(i));
Extrema_ExtPC myExtPC(pv,TheCurve);
if (myExtPC.IsDone()) {
gp_Pnt p1b,p2b;
Standard_Real thepmin = TheCurve.FirstParameter();
myExtPC.TrimmedSquareDistances(Dist2Min,Dist2,p1b,p2b);
if (Dist2 < Dist2Min) {
thepmin = TheCurve.LastParameter();
}
for (k=1; k<=myExtPC.NbExt(); k++) {
Dist2 = myExtPC.SquareDistance(k);
if (Dist2 < Dist2Min) {
Dist2Min = Dist2;
thepmin = myExtPC.Point(k).Parameter();
}
}
if (Dist2Min < Glob2Min) {
Glob2Min = Dist2Min;
pmin = thepmin;
imin = i;
}
}
}
if (imin == 0) {
return;
}
Newc = i2s.Line(imin);
knownp = pmin;
if (AppS1) {
newCs1 = i2s.LineOnS1(imin);
}
if (AppS2) {
newCs2 = i2s.LineOnS2(imin);
}
}
break;
}
// Determination des vertex par intersection sur Plg ou/et Pld
HAC->Load(Newc);
Standard_Integer nbfois = 2;
TopoDS_Vertex vtx1,vtx2;
Standard_Real p1=0,p2=0;
Standard_Boolean IsLeft=Standard_False;
if (Choice == 1) {
// edge retrouve : on ne fait qu`une seule intersection
// il faut utiliser Plg ou Pld
Standard_Integer indedgf = theMapEF.FindIndex(edg1);
for (itl.Initialize(theMapEF(indedgf)); itl.More(); itl.Next()) {
if (Contains(myMap(F),itl.Value())) {
if (Contains(theLeft,itl.Value())) {
HAS->Load(NewSg);
IsLeft = Standard_True;
}
else {
HAS->Load(NewSd);
IsLeft = Standard_False;
}
nbfois = 1;
vtx2 = vtx;
p2 = knownp;
break;
}
}
if (!itl.More()) {
std::cout << "LocOpe_SplitDrafts: betite probleme "<< std::endl;
return;
}
}
else {
HAS->Load(NewSg);
}
for (Standard_Integer it = 1; it<=nbfois; it++) {
if (it == 2) {
HAS->Load(NewSd);
}
intcs.Perform(HAC,HAS);
if (!intcs.IsDone()) {
return; // voir ce qu`on peut faire de mieux
}
Standard_Integer imin = 1;
Standard_Real delta = Abs(knownp - intcs.Point(1).W());
for (Standard_Integer i = 2; i<= intcs.NbPoints(); i++) {
Standard_Real newdelta = Abs(knownp - intcs.Point(i).W());
if (newdelta < delta) {
imin = i;
delta = newdelta;
}
}
if (it == 1) {
B.MakeVertex(vtx1,intcs.Point(imin).Pnt(),Precision::Confusion());
p1 = intcs.Point(imin).W();
knownp = p1;
}
else {
B.MakeVertex(vtx2,intcs.Point(imin).Pnt(),Precision::Confusion());
p2 = intcs.Point(imin).W();
}
}
if (Abs(p1-p2) > Precision::PConfusion()) {
TopoDS_Edge NewEdge;
B.MakeEdge(NewEdge,Newc,Precision::Confusion());
if (p1 < p2) {
B.Add(NewEdge,vtx1.Oriented(TopAbs_FORWARD));
B.Add(NewEdge,vtx2.Oriented(TopAbs_REVERSED));
}
else {
B.Add(NewEdge,vtx1.Oriented(TopAbs_REVERSED));
B.Add(NewEdge,vtx2.Oriented(TopAbs_FORWARD));
}
B.UpdateVertex(vtx1,p1,NewEdge,Precision::Confusion());
B.UpdateVertex(vtx2,p2,NewEdge,Precision::Confusion());
if (!newCs1.IsNull()) {
B.UpdateEdge(NewEdge,newCs1,
TopoDS::Face(MapEV.FindFromKey(edg1)),
Precision::Confusion());
}
if (!newCs2.IsNull()) {
B.UpdateEdge(NewEdge,newCs2,
TopoDS::Face(MapEV.FindFromKey(edg2)),
Precision::Confusion());
}
MapEV.Add(vtx,NewEdge);
if (Choice == 1) {
TopoDS_Shape aLocalEdge = Ebind.EmptyCopied();
TopoDS_Edge NE = TopoDS::Edge(aLocalEdge);
// TopoDS_Edge NE = TopoDS::Edge(Ebind.EmptyCopied());
for (exp2.Init(Ebind,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
const TopoDS_Vertex& thevtx = TopoDS::Vertex(exp2.Current());
if (thevtx.IsSame(vtx)) {
B.Add(NE,vtx1.Oriented(thevtx.Orientation()));
B.UpdateVertex(vtx1,p1,NE,Precision::Confusion());
}
else {
B.Add(NE,thevtx);
Standard_Real theprm = BRep_Tool::Parameter(thevtx,Ebind);
B.UpdateVertex(thevtx,theprm,NE,BRep_Tool::Tolerance(thevtx));
}
}
MapSonS.Bind(Ebind,NE.Oriented(TopAbs_FORWARD));
if (IsLeft) {
TopTools_ListOfShape thelist5;
MapSg.Bind(vtx, thelist5);
MapSg(vtx).Append(vtx1);
}
else {
TopTools_ListOfShape thelist6;
MapSd.Bind(vtx, thelist6);
MapSd(vtx).Append(vtx1);
}
}
else {
TopTools_ListOfShape thelist7, thelist8;
MapSg.Bind(vtx, thelist7);
MapSd.Bind(vtx, thelist8);
MapSg(vtx).Append(vtx1);
MapSd(vtx).Append(vtx2);
}
}
else {
MapEV.Add(vtx,vtx2); // on peut avoir vtx2 = vtx si choix == 1
if (Choice == 1) {
if (IsLeft) {
TopTools_ListOfShape thelist9;
MapSg.Bind(vtx, thelist9);
MapSg(vtx).Append(vtx);
}
else {
TopTools_ListOfShape thelist10;
MapSd.Bind(vtx, thelist10);
MapSd(vtx).Append(vtx);
}
}
else {
TopTools_ListOfShape thelist11, thelist12;
MapSg.Bind(vtx, thelist11);
MapSd.Bind(vtx, thelist12);
MapSg(vtx).Append(vtx2);
MapSd(vtx).Append(vtx2);
}
}
}
}
theMap.Clear();
for (exp.Init(theW,TopAbs_EDGE); exp.More(); exp.Next()) {
const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
if (!theMap.Add(edg)) { // precaution sans doute inutile...
continue;
}
Standard_Integer indedg = MapEV.FindIndex(edg);
TopoDS_Face& GenF = TopoDS::Face(MapEV(indedg));
TopTools_ListOfShape thelist13, thelist14;
MapSg.Bind(edg, thelist13); // genere a gauche
MapSd.Bind(edg, thelist14); // genere a droite
TopoDS_Vertex Vf,Vl;
TopoDS_Shape aLocalEdge = edg.Oriented(TopAbs_FORWARD);
TopExp::Vertices(TopoDS::Edge(aLocalEdge),Vf,Vl);
// TopExp::Vertices(TopoDS::Edge(edg.Oriented(TopAbs_FORWARD)),Vf,Vl);
TopoDS_Shape Gvf = MapEV.FindFromKey(Vf);
TopoDS_Shape Gvl = MapEV.FindFromKey(Vl);
/* Le code suivant est OK. On essaie de l`ameliorer
if (Gvf.ShapeType() == TopAbs_VERTEX &&
Gvl.ShapeType() == TopAbs_VERTEX) {
// en fait on doit pouvoir avoir 1 face a 2 cotes...
if (Gvf.IsSame(Vf)) {
MapW(edg) = edg;
MapSg(edg).Append(edg.Oriented(TopAbs_FORWARD));
MapSd(edg).Append(edg.Oriented(TopAbs_FORWARD));
}
else {
TopoDS_Edge NewEdg = NewEdge(edg,
GenF,NewSg,
TopoDS::Vertex(Gvf),
TopoDS::Vertex(Gvl));
if (NewEdg.IsNull()) {
return;
}
MapW(edg) = NewEdg;
MapSg(edg).Append(NewEdg);
MapSd(edg).Append(NewEdg);
}
}
else if (Gvf.ShapeType() == TopAbs_VERTEX ||
Gvl.ShapeType() == TopAbs_VERTEX) { // face triangulaire
TopoDS_Vertex Vfd,Vld,Vfg,Vlg;
if (Gvf.ShapeType() == TopAbs_VERTEX) {
Vfg = TopoDS::Vertex(Gvf);
Vfd = Vfg;
Vlg = TopoDS::Vertex(MapSg(Vl).First());
Vld = TopoDS::Vertex(MapSd(Vl).First());
}
else {
Vlg = TopoDS::Vertex(Gvl);
Vld = Vlg;
Vfg = TopoDS::Vertex(MapSg(Vf).First());
Vfd = TopoDS::Vertex(MapSd(Vf).First());
}
TopoDS_Edge NewEdgg = NewEdge(edg,GenF,NewSg,Vfg,Vlg);
if (NewEdgg.IsNull()) {
return;
}
TopoDS_Edge NewEdgd = NewEdge(edg,GenF,NewSd,Vfd,Vld);
if (NewEdgg.IsNull()) {
return;
}
MapSg(edg).Append(NewEdgg);
MapSd(edg).Append(NewEdgd);
TopTools_ListOfShape theedges;
theedges.Append(NewEdgg);
theedges.Append(NewEdgd);
if (Gvf.ShapeType() == TopAbs_EDGE) {
theedges.Append(Gvf);
}
else {//if (Gvl.ShapeType() == TopAbs_EDGE) {
theedges.Append(Gvl);
}
MakeFace(GenF,theedges);
MapW(edg) = GenF;
}
else {
// une face a 4 cotes
TopoDS_Vertex Vfd,Vld,Vfg,Vlg;
Vfg = TopoDS::Vertex(MapSg(Vf).First());
Vfd = TopoDS::Vertex(MapSd(Vf).First());
Vlg = TopoDS::Vertex(MapSg(Vl).First());
Vld = TopoDS::Vertex(MapSd(Vl).First());
TopoDS_Vertex VVf1,VVl1,VVf2,VVl2;
TopExp::Vertices(TopoDS::Edge(Gvf.Oriented(TopAbs_FORWARD)),VVf1,VVl1);
TopExp::Vertices(TopoDS::Edge(Gvl.Oriented(TopAbs_FORWARD)),VVf2,VVl2);
TopoDS_Edge NewEdgg = NewEdge(edg,GenF,NewSg,Vfg,Vlg);
if (NewEdgg.IsNull()) {
return;
}
TopoDS_Edge NewEdgd = NewEdge(edg,GenF,NewSd,Vfd,Vld);
if (NewEdgd.IsNull()) {
return;
}
if ((VVf1.IsSame(Vfg) && VVf2.IsSame(Vlg)) ||
(VVf1.IsSame(Vfd) && VVf2.IsSame(Vld))) {
// 4 cotes
MapSg(edg).Append(NewEdgg);
MapSd(edg).Append(NewEdgd);
TopTools_ListOfShape theedges;
theedges.Append(NewEdgg);
theedges.Append(NewEdgd);
theedges.Append(Gvf);
theedges.Append(Gvl);
MakeFace(GenF,theedges);
MapW(edg) = GenF;
}
else {
#ifdef OCCT_DEBUG
std::cout << "Pb d'analyse" << std::endl;
#endif
return;
}
}
*/
// nouveau code
TopoDS_Vertex Vfd,Vld,Vfg,Vlg;
if (Gvf.ShapeType() == TopAbs_VERTEX) {
Vfg = TopoDS::Vertex(Gvf);
Vfd = Vfg;
}
else {
Vfg = TopoDS::Vertex(MapSg(Vf).First());
Vfd = TopoDS::Vertex(MapSd(Vf).First());
}
if (Gvl.ShapeType() == TopAbs_VERTEX) {
Vlg = TopoDS::Vertex(Gvl);
Vld = Vlg;
}
else {
Vlg = TopoDS::Vertex(MapSg(Vl).First());
Vld = TopoDS::Vertex(MapSd(Vl).First());
}
TopoDS_Edge NewEdgg = NewEdge(edg,GenF,NewSg,Vfg,Vlg);
if (NewEdgg.IsNull()) {
return;
}
TopoDS_Edge NewEdgd = NewEdge(edg,GenF,NewSd,Vfd,Vld);
if (NewEdgg.IsNull()) {
return;
}
Standard_Boolean isedg = Standard_False;
if (Gvf.ShapeType() == TopAbs_VERTEX &&
Gvl.ShapeType() == TopAbs_VERTEX) {
// edg ou face a 2 cotes
// Comparaison NewEdgg et NewEdgd
Standard_Real fg,lg,fd,ld;
Handle(Geom_Curve) Cg = BRep_Tool::Curve(NewEdgg,fg,lg);
Handle(Geom_Curve) Cd = BRep_Tool::Curve(NewEdgd,fd,ld);
Standard_Real prmg = (fg+lg)/2.;
Standard_Real prmd = (fd+ld)/2.;
gp_Pnt pg = Cg->Value(prmg);
gp_Pnt pd = Cd->Value(prmd);
Standard_Real Tol = Max(BRep_Tool::Tolerance(NewEdgg),
BRep_Tool::Tolerance(NewEdgg));
if (pg.SquareDistance(pd) <= Tol*Tol) {
isedg = Standard_True;
// raffinement pour essayer de partager l`edge de depart...
Standard_Boolean modified = Standard_True;
if (Gvf.IsSame(Vf) && Gvl.IsSame(Vl)) {
// Comparaison avec l`edge de depart
Cd = BRep_Tool::Curve(edg,fd,ld);
prmd = (fd+ld)/2.;
pd = Cd->Value(prmd);
Tol = Max(BRep_Tool::Tolerance(NewEdgg),
BRep_Tool::Tolerance(edg));
if (pg.SquareDistance(pd) <= Tol*Tol) {
modified = Standard_False;
}
}
if (!modified) {
MapW(edg) = edg;
MapSg(edg).Append(edg);
MapSd(edg).Append(edg);
}
else {
MapW(edg) = NewEdgg;
MapSg(edg).Append(NewEdgg);
MapSd(edg).Append(NewEdgg);
}
}
}
if (!isedg) {
// face a 2 ou 3 ou 4 cotes
MapSg(edg).Append(NewEdgg);
MapSd(edg).Append(NewEdgd);
TopTools_ListOfShape theedges;
theedges.Append(NewEdgg);
theedges.Append(NewEdgd);
if (Gvf.ShapeType() == TopAbs_EDGE) {
theedges.Append(Gvf);
}
if (Gvl.ShapeType() == TopAbs_EDGE) {
theedges.Append(Gvl);
}
MakeFace(GenF,theedges);
MapW(edg) = GenF;
}
}
TopTools_MapOfShape mapedgadded;
TopTools_ListOfShape thefaces;
for (itl.Initialize(myMap(F)); itl.More(); itl.Next()) {
const TopoDS_Face& fac = TopoDS::Face(itl.Value());
theMap.Clear();
TopoDS_Face DrftFace; // elle est FORWARD
Standard_Boolean IsLeft;
if (Contains(theLeft,fac)) {
B.MakeFace(DrftFace,NewSg,BRep_Tool::Tolerance(fac));
IsLeft = Standard_True;
}
else {
B.MakeFace(DrftFace,NewSd,BRep_Tool::Tolerance(fac));
IsLeft = Standard_False;
}
TopExp_Explorer exp3;
for (exp3.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
exp3.More(); exp3.Next()) {
const TopoDS_Shape& wir = exp3.Current();
TopoDS_Wire NewWireOnF;
B.MakeWire(NewWireOnF);
for (exp.Init(wir.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
exp.More(); exp.Next()) {
const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
if (!theMap.Add(edg)) { // precaution sans doute inutile...
continue;
}
if (MapW.IsBound(edg)) { // edge du wire d`origine
TopTools_ListIteratorOfListOfShape itld;
TopAbs_Orientation ored = edg.Orientation();
if (IsLeft) {
itld.Initialize(MapSg(edg));
}
else {
itld.Initialize(MapSd(edg));
}
for (; itld.More(); itld.Next()) {
if (itld.Value().Orientation() == TopAbs_REVERSED) {
ored = TopAbs::Reverse(ored);
}
TopoDS_Shape aLocalEdge = itld.Value().Oriented(ored);
B.Add(NewWireOnF,TopoDS::Edge(aLocalEdge));
// B.Add(NewWireOnF,TopoDS::Edge(itld.Value().Oriented(ored)));
}
}
else {
Handle(Geom_Surface) NewS;
if (IsLeft) {
NewS = NewSg;
}
else {
NewS = NewSd;
}
Standard_Integer indedg = MapEV.FindIndex(edg);
const TopoDS_Face& GenF = TopoDS::Face(MapEV(indedg));
TopoDS_Vertex Vf,Vl;
TopoDS_Shape aLocalEdge = edg.Oriented(TopAbs_FORWARD);
TopExp::Vertices(TopoDS::Edge(aLocalEdge),Vf,Vl);
// TopExp::Vertices(TopoDS::Edge(edg.Oriented(TopAbs_FORWARD)),Vf,Vl);
TopoDS_Shape Gvf = MapEV.FindFromKey(Vf);
TopoDS_Shape Gvl = MapEV.FindFromKey(Vl);
if (Gvf.ShapeType() == TopAbs_VERTEX &&
Gvl.ShapeType() == TopAbs_VERTEX) {
if (!Gvf.IsSame(Vf) || !Gvl.IsSame(Vl)) {
TopoDS_Edge NewEdg = NewEdge(edg,GenF,NewS,
TopoDS::Vertex(Gvf),
TopoDS::Vertex(Gvl));
if (NewEdg.IsNull()) {
return;
}
MapSonS.Bind(edg,NewEdg);
if (NewEdg.Orientation() == TopAbs_REVERSED) {
NewEdg.Orientation(TopAbs::Reverse(edg.Orientation()));
}
else {
NewEdg.Orientation(edg.Orientation());
}
B.Add(NewWireOnF,NewEdg);
}
else { // Frozen???
B.Add(NewWireOnF,edg);
}
}
else {
TopoDS_Vertex Vff,Vll;
if (Gvf.ShapeType() == TopAbs_VERTEX) {
Vff = TopoDS::Vertex(Gvf);
}
else {
if (IsLeft) {
Vff = TopoDS::Vertex(MapSg(Vf).First());
}
else {
Vff = TopoDS::Vertex(MapSd(Vf).First());
}
}
if (Gvl.ShapeType() == TopAbs_VERTEX) {
Vll = TopoDS::Vertex(Gvl);
}
else {
if (IsLeft) {
Vll = TopoDS::Vertex(MapSg(Vl).First());
}
else {
Vll = TopoDS::Vertex(MapSd(Vl).First());
}
}
TopoDS_Edge NewEdg = NewEdge(edg,GenF,NewS,Vff,Vll);
if (NewEdg.IsNull()) {
return;
}
if (!MapW.IsBound(Vf) && !MapW.IsBound(Vl)) {
MapSonS.Bind(edg,NewEdg);
}
// else if (MapW.IsBound(Vf) && MapW.IsBound(Vl)) {
// }
else {
if (MapW.IsBound(Vf)) {
if (Gvf.ShapeType() != TopAbs_EDGE ||
mapedgadded.Contains(Gvf)) {
MapSonS.Bind(edg,NewEdg);
}
else {
TopoDS_Wire NewWir;
B.MakeWire(NewWir);
B.Add(NewWir,NewEdg);
TopoDS_Vertex Vf2,Vl2;
TopExp::Vertices(TopoDS::Edge(Gvf),Vf2,Vl2);
//TopAbs_Orientation ornw = NewEdg.Orientation();
// ici bug orientation : voir tspdrft6
// if ((ornw == TopAbs_FORWARD && Vl2.IsSame(Vff)) ||
// (ornw == TopAbs_REVERSED && Vl2.IsSame(Vll))) {
if (Vl2.IsSame(Vff)) {
B.Add(NewWir,Gvf.Oriented(TopAbs_FORWARD));
}
else {
B.Add(NewWir,Gvf.Oriented(TopAbs_REVERSED));
}
mapedgadded.Add(Gvf);
MapSonS.Bind(edg,NewWir); // NewWire est FORWARD
}
}
else {
if (Gvl.ShapeType() != TopAbs_EDGE ||
mapedgadded.Contains(Gvl)) {
MapSonS.Bind(edg,NewEdg);
}
else {
TopoDS_Wire NewWir;
B.MakeWire(NewWir);
B.Add(NewWir,NewEdg);
TopoDS_Vertex Vf2,Vl2;
TopExp::Vertices(TopoDS::Edge(Gvl),Vf2,Vl2);
//TopAbs_Orientation ornw = NewEdg.Orientation();
// ici bug orientation : voir tspdrft6
// if ((ornw == TopAbs_FORWARD && Vl2.IsSame(Vff)) ||
// (ornw == TopAbs_REVERSED && Vl2.IsSame(Vll))) {
if (Vf2.IsSame(Vll)) {
B.Add(NewWir,Gvl.Oriented(TopAbs_FORWARD));
}
else {
B.Add(NewWir,Gvl.Oriented(TopAbs_REVERSED));
}
mapedgadded.Add(Gvl);
MapSonS.Bind(edg,NewWir); // NewWire est FORWARD
}
}
}
if (NewEdg.Orientation() == TopAbs_REVERSED) {
NewEdg.Orientation(TopAbs::Reverse(edg.Orientation()));
}
else {
NewEdg.Orientation(edg.Orientation());
}
B.Add(NewWireOnF,NewEdg);
}
}
}
B.Add(DrftFace,NewWireOnF.Oriented(wir.Orientation()));
}
thefaces.Append(DrftFace);
}
BRepTools_Substitution theSubs;
TopTools_DataMapIteratorOfDataMapOfShapeShape itdmss;
for (itdmss.Initialize(MapSonS);
itdmss.More(); itdmss.Next()) {
TopTools_ListOfShape lsubs;
for (exp.Init(itdmss.Value(),TopAbs_EDGE); exp.More(); exp.Next()) {
lsubs.Append(exp.Current());
}
theSubs.Substitute(itdmss.Key(),lsubs);
}
// on reconstruit les faces
for (exp.Init(Res,TopAbs_FACE); exp.More(); exp.Next()) {
if (Contains(myMap(F),exp.Current())) {
continue;
}
theSubs.Build(exp.Current());
}
// Stockage des descendants
// for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdmsls(myMap);
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdmsls(myMap) ;
for ( ; itdmsls.More(); itdmsls.Next()) {
if (itdmsls.Key().ShapeType() == TopAbs_EDGE) {
TopTools_ListOfShape thedesc;
theMap.Clear();
for (itl.Initialize(itdmsls.Value());itl.More(); itl.Next()) {
if (theMap.Add(MapW(itl.Value()))) {
thedesc.Append(MapW(itl.Value()));
}
}
myMap(itdmsls.Key()) = thedesc;
}
else if (itdmsls.Key().IsSame(F)) {
myMap(F).Clear();
for (itl.Initialize(thefaces); itl.More(); itl.Next()) {
myMap(F).Append(itl.Value());
}
}
else {
TopTools_ListOfShape thedesc;
theMap.Clear();
for (itl.Initialize(itdmsls.Value());itl.More(); itl.Next()) {
if (theSubs.IsCopied(itl.Value())) {
if (theSubs.Copy(itl.Value()).Extent() != 1) {
#ifdef OCCT_DEBUG
std::cout << "Invalid number of descendant" << std::endl;
#endif
return;
}
else {
if (theMap.Add(theSubs.Copy(itl.Value()).First())) {
thedesc.Append(theSubs.Copy(itl.Value()).First());
}
}
}
else if (theMap.Add(itl.Value())) {
thedesc.Append(itl.Value());
}
}
myMap(itdmsls.Key()) = thedesc;
}
}
theMap.Clear();
thefaces.Clear();
for (itdmsls.Initialize(myMap);itdmsls.More(); itdmsls.Next()) {
for (itl.Initialize(itdmsls.Value());itl.More(); itl.Next()) {
if (itl.Value().ShapeType() == TopAbs_FACE &&
theMap.Add(itl.Value())) {
thefaces.Append(itl.Value());
}
}
}
LocOpe_BuildShape BS(thefaces);
myResult = BS.Shape();
}
//=======================================================================
//function : Shape
//purpose :
//=======================================================================
const TopoDS_Shape& LocOpe_SplitDrafts::Shape () const
{
if (myResult.IsNull()) {
throw StdFail_NotDone();
}
return myResult;
}
//=======================================================================
//function : ShapesFromShape
//purpose :
//=======================================================================
const TopTools_ListOfShape& LocOpe_SplitDrafts::ShapesFromShape
(const TopoDS_Shape& S) const
{
if (myResult.IsNull()) {
throw StdFail_NotDone();
}
return myMap(S);
}
//=======================================================================
//function : NewPlane
//purpose :
//=======================================================================
static Standard_Boolean NewPlane(const TopoDS_Face& F,
const gp_Dir& Extr,
const gp_Pln& Neutr,
const Standard_Real Ang,
gp_Pln& Newpl,
gp_Ax1& NormalF,
const Standard_Boolean Modify)
{
// Determination du nouveau plan incline
Handle(Geom_Surface) S = BRep_Tool::Surface(F);
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()) {
return Standard_False;
}
gp_Pln Plorig = P->Pln();
if (!Modify) {
Newpl = Plorig;
NormalF = Newpl.Axis();
if ((Newpl.Direct() && F.Orientation() == TopAbs_REVERSED) ||
(!Newpl.Direct() && F.Orientation() == TopAbs_FORWARD)) {
NormalF.Reverse();
}
return Standard_True;
}
gp_Ax1 Axe;
Standard_Real Theta;
IntAna_QuadQuadGeo i2pl(Plorig,Neutr,
Precision::Angular(),Precision::Confusion());
if (i2pl.IsDone() && i2pl.TypeInter() == IntAna_Line) {
gp_Lin LinInters = i2pl.Line(1);
gp_Dir nx = LinInters.Direction();
NormalF = Plorig.Axis();
gp_Dir ny = NormalF.Direction().Crossed(nx);
Standard_Real a = Extr.Dot(nx);
if (Abs(a) <=1-Precision::Angular()) {
Standard_Real b = Extr.Dot(ny);
Standard_Real c = Extr.Dot(NormalF.Direction());
Standard_Boolean direct(Plorig.Direct());
TopAbs_Orientation Oris = F.Orientation();
if ((direct && Oris == TopAbs_REVERSED) ||
(!direct && Oris == TopAbs_FORWARD)) {
b = -b;
c = -c;
NormalF.Reverse();
}
Standard_Real denom = Sqrt(1-a*a);
Standard_Real Sina = Sin(Ang);
if (denom>Abs(Sina)) {
Standard_Real phi = ATan2(b/denom,c/denom);
Standard_Real theta0 = ACos(Sina/denom);
Theta = theta0 - phi;
if (Cos(Theta) <0.) {
Theta = -theta0 -phi;
}
Axe = LinInters.Position();
Newpl = Plorig.Rotated(Axe,Theta);
return Standard_True;
}
}
}
std::cout << "fin newplane return standard_false" << std::endl;
return Standard_False;
}
//=======================================================================
//function : MakeFace
//purpose :
//=======================================================================
static void MakeFace(TopoDS_Face& F,
TopTools_ListOfShape& ledg)
{
// ledg est une liste d'edge
BRep_Builder B;
// Verification de l`existence des p-curves. Celles qui manquent
// correspondent necessairement a des isos (et meme des iso u).
Standard_Real f,l;
// for (TopTools_ListIteratorOfListOfShape itl(ledg);
TopTools_ListIteratorOfListOfShape itl(ledg) ;
for ( ; itl.More(); itl.Next()) {
const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
if (C2d.IsNull()) {
BRep_Tool::Range(edg,f,l);
TopoDS_Vertex V1,V2;
TopExp::Vertices(edg,V1,V2);
TopTools_ListIteratorOfListOfShape itl2;
for (itl2.Initialize(ledg);
itl2.More(); itl2.Next()) {
const TopoDS_Edge& edg2 = TopoDS::Edge(itl2.Value());
if (edg2.IsSame(edg)) {
continue;
}
TopoDS_Vertex Vp1,Vp2;
TopExp::Vertices(edg2,Vp1,Vp2);
if (Vp1.IsSame(V1) || Vp2.IsSame(V1) ||
Vp1.IsSame(V2) || Vp2.IsSame(V2)) {
Standard_Real f2,l2;
Handle(Geom2d_Curve) C22d = BRep_Tool::CurveOnSurface(edg2,F,f2,l2);
if (!C22d.IsNull()) {
gp_Pnt2d pt2d;
if (Vp1.IsSame(V1)) {
pt2d = C22d->Value(f2);
pt2d.SetY(pt2d.Y()-f);
}
else if (Vp2.IsSame(V1)) {
pt2d = C22d->Value(l2);
pt2d.SetY(pt2d.Y()-f);
}
else if (Vp1.IsSame(V2)) {
pt2d = C22d->Value(f2);
pt2d.SetY(pt2d.Y()-l);
}
else if (Vp2.IsSame(V2)) {
pt2d = C22d->Value(l2);
pt2d.SetY(pt2d.Y()-l);
}
C2d = new Geom2d_Line(pt2d,gp::DY2d());
B.UpdateEdge(edg,C2d,F,BRep_Tool::Tolerance(edg));
break;
}
}
}
if (C2d.IsNull()) {
std::cout << "Ca merde violemment" << std::endl;
}
}
}
TopTools_ListOfShape lwires;
Standard_Boolean alldone = ledg.IsEmpty();
while (!alldone) {
TopoDS_Wire Wnew;
B.MakeWire(Wnew);
TopoDS_Shape aLocalShapeCur = ledg.First();
const TopoDS_Edge& edg = TopoDS::Edge(aLocalShapeCur);
// const TopoDS_Edge& edg = TopoDS::Edge(ledg.First());
TopoDS_Vertex VFirst,VLast;
if (edg.Orientation() == TopAbs_FORWARD) {
TopExp::Vertices(edg,VFirst,VLast);
}
else {
TopExp::Vertices(edg,VLast,VFirst);
}
B.Add(Wnew,edg);
ledg.RemoveFirst();
// on suppose VFirst et VLast non nuls
Standard_Boolean wdone = (ledg.IsEmpty() || VFirst.IsSame(VLast));
while (!wdone) {
TopoDS_Vertex VF,VL;
TopAbs_Orientation oredg = TopAbs_FORWARD;
for (itl.Initialize(ledg); itl.More(); itl.Next()) {
const TopoDS_Edge& edg2 = TopoDS::Edge(itl.Value());
TopoDS_Shape aLocalShape = edg2.Oriented(TopAbs_FORWARD);
TopExp::Vertices(TopoDS::Edge(aLocalShape),VF,VL);
// TopExp::Vertices(TopoDS::Edge(edg2.Oriented(TopAbs_FORWARD)),VF,VL);
if (VF.IsSame(VLast)) {
VLast = VL;
oredg = TopAbs_FORWARD;
break;
}
else if (VL.IsSame(VFirst)) {
VFirst = VF;
oredg = TopAbs_FORWARD;
break;
}
else if (VF.IsSame(VFirst)) {
VFirst = VL;
oredg = TopAbs_REVERSED;
break;
}
else if (VL.IsSame(VLast)) {
VLast = VF;
oredg = TopAbs_REVERSED;
break;
}
}
if (!itl.More()) {
wdone = Standard_True;
}
else {
TopoDS_Shape aLocalShape = itl.Value().Oriented(oredg);
B.Add(Wnew,TopoDS::Edge(aLocalShape));
// B.Add(Wnew,TopoDS::Edge(itl.Value().Oriented(oredg)));
ledg.Remove(itl);
wdone = (ledg.IsEmpty() || VFirst.IsSame(VLast));
}
}
lwires.Append(Wnew);
alldone = ledg.IsEmpty();
}
F.Orientation(TopAbs_FORWARD);
for (itl.Initialize(lwires); itl.More(); itl.Next()) {
TopoDS_Shape aLocalShape = F.EmptyCopied();
TopoDS_Face NewFace = TopoDS::Face(aLocalShape);
// TopoDS_Face NewFace = TopoDS::Face(F.EmptyCopied());
B.Add(NewFace,itl.Value());
GProp_GProps GP;
BRepGProp::SurfaceProperties(NewFace,GP);
if (GP.Mass() < 0) {
itl.ChangeValue().Reverse();
}
}
if (lwires.Extent() == 1) {
B.Add(F,lwires.First());
}
else {
std::cout << "Not yet implemented : nbwire >= 2" << std::endl;
}
}
//=======================================================================
//function : Contains
//purpose :
//=======================================================================
static Standard_Boolean Contains(const TopTools_ListOfShape& ll,
const TopoDS_Shape& s)
{
TopTools_ListIteratorOfListOfShape itl;
for (itl.Initialize(ll); itl.More(); itl.Next()) {
if (itl.Value().IsSame(s)) {
return Standard_True;
}
}
return Standard_False;
}
//=======================================================================
//function : Contains
//purpose :
//=======================================================================
static TopoDS_Edge NewEdge(const TopoDS_Edge& edg,
const TopoDS_Face& F,
const Handle(Geom_Surface)& NewS,
const TopoDS_Vertex& V1,
const TopoDS_Vertex& V2)
{
TopoDS_Edge NewEdg;
Handle(Geom_Surface) S1 = BRep_Tool::Surface(F);
Standard_Boolean AppS1 = Standard_False;
if (S1->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
AppS1 = Standard_True;
}
GeomInt_IntSS i2s(S1,NewS,Precision::Confusion(),Standard_True,AppS1);
if (!i2s.IsDone() || i2s.NbLines() <= 0) {
return NewEdg;
}
BRep_Builder B;
// Standard_Real pmin, Dist, DistMin;
Standard_Real Dist2, Dist2Min;
Standard_Real prmf=0,prml=0;
GeomAdaptor_Curve TheCurve;
Standard_Integer i,k;
gp_Pnt pvf = BRep_Tool::Pnt(V1);
gp_Pnt pvl = BRep_Tool::Pnt(V2);
for (i=1; i<= i2s.NbLines(); i++) {
TheCurve.Load(i2s.Line(i));
Extrema_ExtPC myExtPC(pvf,TheCurve);
if (myExtPC.IsDone()) {
gp_Pnt p1b,p2b;
Standard_Real thepmin = TheCurve.FirstParameter();
myExtPC.TrimmedSquareDistances(Dist2Min,Dist2,p1b,p2b);
if (Dist2 < Dist2Min && !TheCurve.IsPeriodic()) {
Dist2Min = Dist2;
thepmin = TheCurve.LastParameter();
}
for (k=1; k<=myExtPC.NbExt(); k++) {
Dist2 = myExtPC.SquareDistance(k);
if (Dist2 < Dist2Min) {
Dist2Min = Dist2;
thepmin = myExtPC.Point(k).Parameter();
}
}
if (Dist2Min <= Precision::SquareConfusion()) {
prmf = thepmin;
myExtPC.Perform(pvl);
if (myExtPC.IsDone()) {
thepmin = TheCurve.LastParameter();
myExtPC.TrimmedSquareDistances(Dist2,Dist2Min,p1b,p2b);
if (Dist2 < Dist2Min && !TheCurve.IsClosed()) {
Dist2Min = Dist2;
thepmin = TheCurve.FirstParameter();
}
for (k=1; k<=myExtPC.NbExt(); k++) {
Dist2 = myExtPC.SquareDistance(k);
if (Dist2 < Dist2Min) {
Dist2Min = Dist2;
thepmin = myExtPC.Point(k).Parameter();
}
}
if (Dist2Min <= Precision::SquareConfusion()) {
prml = thepmin;
break;
}
}
}
}
}
if (i <= i2s.NbLines()) {
Standard_Boolean rev = Standard_False;
TopoDS_Vertex Vf = V1;
TopoDS_Vertex Vl = V2;
const Handle(Geom_Curve)& Cimg = i2s.Line(i);
Handle(Geom2d_Curve) Cimg2d;
if (AppS1) {
Cimg2d = i2s.LineOnS1(i);
}
if (Cimg->IsPeriodic()) {
Standard_Real period = Cimg->Period();
Standard_Real imf = Cimg->FirstParameter();
Standard_Real iml = Cimg->LastParameter();
Standard_Real f,l;
BRep_Tool::Range(edg,f,l);
Standard_Real delt = l-f;
Standard_Real delt1 = Abs(prml-prmf);
Standard_Real delt2 = Abs(period-delt1);
if (delt1 == 0 || delt2 == 0) {
// prmf = 0;
// prml = period;
prmf = imf;
prml = iml;
}
else {
if (Abs(delt1-delt) > Abs(delt2-delt)) {
// le bon ecart est delt2...
if (prml > prmf) {
if (prml < iml) {
prmf += period;
}
else {
prml -= period;
}
}
else {
if (prmf < iml) {
prml += period;
}
else {
prmf -= period;
}
}
}
else if (Abs(delt1-delt) < Abs(delt2-delt)) {
if (prmf >= iml && prml >= iml) {
prmf -= period;
prml -= period;
}
else if (prmf <= imf && prml <= imf) {
prmf += period;
prml += period;
}
}
else { // egalite; on priveligie l'ordre f,l
if (prmf > prml) {
prmf -= period;
}
if (prmf >= iml && prml >= iml) {
prmf -= period;
prml -= period;
}
else if (prmf <= imf && prml <= imf) {
prmf += period;
prml += period;
}
}
}
#ifdef OCCT_DEBUG
Standard_Real ptol = Precision::PConfusion();
if (prmf < imf - ptol || prmf > iml + ptol ||
prml < imf - ptol || prml > iml + ptol) {
std::cout << "Ca ne va pas aller" << std::endl;
}
#endif
}
if (S1->IsUPeriodic()) {
Standard_Real speriod = S1->UPeriod();
// Standard_Real f,l;
gp_Pnt2d pf,pl;
pf = Cimg2d->Value(prmf);
pl = Cimg2d->Value(prml);
Standard_Real Uf = pf.X();
Standard_Real Ul = pl.X();
Standard_Real ptra = 0.0;
Standard_Real Ustart = Min(Uf,Ul);
while (Ustart < -Precision::PConfusion()) {
Ustart += speriod;
ptra += speriod;
}
while (Ustart > speriod - Precision::PConfusion()) {
Ustart -= speriod;
ptra -= speriod;
}
if (ptra != 0) {
Cimg2d->Translate(gp_Vec2d(ptra,0.));
}
}
if (prmf < prml) {
Vf.Orientation(TopAbs_FORWARD);
Vl.Orientation(TopAbs_REVERSED);
}
else {
Vf.Orientation(TopAbs_REVERSED);
Vl.Orientation(TopAbs_FORWARD);
rev = Standard_True;
}
B.MakeEdge(NewEdg,Cimg,Precision::Confusion());
B.Add(NewEdg,Vf);
B.Add(NewEdg,Vl);
B.UpdateVertex(Vf,prmf,NewEdg,Precision::Confusion());
B.UpdateVertex(Vl,prml,NewEdg,Precision::Confusion());
if (AppS1) {
B.UpdateEdge(NewEdg,Cimg2d,F,Precision::Confusion());
}
if (rev) {
NewEdg.Orientation(TopAbs_REVERSED);
}
}
return NewEdg;
}