mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
1086 lines
29 KiB
C++
1086 lines
29 KiB
C++
// Created on: 1994-03-03
|
|
// Created by: Joelle CHAUVET
|
|
// Copyright (c) 1994-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.
|
|
|
|
// Modified: Mon Jan 12 10:50:10 1998
|
|
// automatic management of origin and orientation
|
|
// with method Organize
|
|
// Modified: Mon Feb 23 09:28:46 1998
|
|
// method Organize with option of projection for closed wires
|
|
// new method SameNumber with option to report cuts
|
|
// + utilities ComputeACR and InsertACR
|
|
// + processing of the case of last point section
|
|
// Modified: Thu Apr 30 15:24:17 1998
|
|
// separation closed / open sections + debug
|
|
// Organize becomes ComputeOrigin and SearchOrigin
|
|
// Modified: Tue Jul 21 16:48:35 1998
|
|
// limited case for Pnext of a twist (BUC60281)
|
|
// Modified: Thu Jul 23 11:38:36 1998
|
|
// calculate the angle of rotation in SearchOrigin
|
|
// Modified: Fri Jul 31 15:14:19 1998
|
|
// IntersectOnWire + MapVLV
|
|
// Modified: Mon Oct 12 09:42:33 1998
|
|
// number of edges in EdgesFromVertex (CTS21570)
|
|
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRep_Tool.hxx>
|
|
#include <BRepAdaptor_Curve.hxx>
|
|
#include <BRepExtrema_DistShapeShape.hxx>
|
|
#include <BRepExtrema_ExtPC.hxx>
|
|
#include <BRepFill.hxx>
|
|
#include <BRepGProp.hxx>
|
|
#include <BRepLib.hxx>
|
|
#include <BRepLib_FindSurface.hxx>
|
|
#include <BRepLib_MakeEdge.hxx>
|
|
#include <BRepLib_MakeFace.hxx>
|
|
#include <BRepLib_MakeVertex.hxx>
|
|
#include <BRepLib_MakeWire.hxx>
|
|
#include <BRepLProp.hxx>
|
|
#include <BRepTools_WireExplorer.hxx>
|
|
#include <GCPnts_AbscissaPoint.hxx>
|
|
#include <Geom2d_Line.hxx>
|
|
#include <Geom_Curve.hxx>
|
|
#include <Geom_Plane.hxx>
|
|
#include <Geom_Surface.hxx>
|
|
#include <Geom_TrimmedCurve.hxx>
|
|
#include <GeomAdaptor_Curve.hxx>
|
|
#include <GeomFill_Generator.hxx>
|
|
#include <gp_Ax3.hxx>
|
|
#include <gp_Circ.hxx>
|
|
#include <gp_Dir.hxx>
|
|
#include <gp_Dir2d.hxx>
|
|
#include <gp_Elips.hxx>
|
|
#include <gp_Lin.hxx>
|
|
#include <gp_Pln.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <gp_Vec.hxx>
|
|
#include <GProp_GProps.hxx>
|
|
#include <GProp_PrincipalProps.hxx>
|
|
#include <Precision.hxx>
|
|
#include <Standard_NoSuchObject.hxx>
|
|
#include <TColStd_Array1OfInteger.hxx>
|
|
#include <TopExp.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
#include <TopLoc_Location.hxx>
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Shape.hxx>
|
|
#include <TopoDS_Shell.hxx>
|
|
#include <TopoDS_Vertex.hxx>
|
|
#include <TopoDS_Wire.hxx>
|
|
#include <TopTools_Array1OfShape.hxx>
|
|
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
|
|
#include <TopTools_DataMapOfShapeListOfShape.hxx>
|
|
#include <TopTools_HSequenceOfShape.hxx>
|
|
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
|
#include <TopTools_IndexedMapOfShape.hxx>
|
|
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
|
#include <TopTools_ListOfShape.hxx>
|
|
#include <TopTools_SequenceOfShape.hxx>
|
|
|
|
static void MakeWire(const TopTools_Array1OfShape& Edges,
|
|
const Standard_Integer rangdeb,
|
|
const Standard_Boolean forward,
|
|
TopoDS_Wire& newwire)
|
|
{
|
|
BRep_Builder BW;
|
|
Standard_Integer rang, nbEdges = Edges.Length();
|
|
BW.MakeWire(newwire);
|
|
if (forward) {
|
|
for (rang=rangdeb;rang<=nbEdges;rang++) {
|
|
BW.Add(newwire,TopoDS::Edge(Edges(rang)));
|
|
}
|
|
for (rang=1;rang<rangdeb;rang++) {
|
|
BW.Add(newwire,TopoDS::Edge(Edges(rang)));
|
|
}
|
|
}
|
|
|
|
else {
|
|
TopoDS_Edge E;
|
|
for (rang=rangdeb;rang>=1;rang--) {
|
|
E = TopoDS::Edge(Edges(rang));
|
|
BW.Add(newwire,E.Reversed());
|
|
}
|
|
for (rang=nbEdges;rang>rangdeb;rang--) {
|
|
E = TopoDS::Edge(Edges(rang));
|
|
BW.Add(newwire, E.Reversed());
|
|
}
|
|
}
|
|
newwire.Orientation(TopAbs_FORWARD);
|
|
newwire.Closed (Standard_True);
|
|
}
|
|
|
|
static void CutEdge(const TopoDS_Edge& CurrentEdge,
|
|
const Standard_Real& Param,
|
|
TopoDS_Edge& E1,
|
|
TopoDS_Edge& E2,
|
|
const TopoDS_Vertex& VRef)
|
|
{
|
|
BRep_Builder B;
|
|
Standard_Real first,last;
|
|
Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
|
|
TopoDS_Vertex Vf, Vl, Vi;
|
|
B.MakeVertex(Vi, C->Value(Param), Precision::Confusion());
|
|
TopExp::Vertices(CurrentEdge, Vf, Vl);
|
|
if (VRef.IsSame(Vf)) {
|
|
E1 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
|
|
E2 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
|
|
}
|
|
else {
|
|
E2 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
|
|
E1 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
|
|
}
|
|
}
|
|
|
|
|
|
static void TrimEdge (const TopoDS_Edge& CurrentEdge,
|
|
const TColStd_SequenceOfReal& CutValues,
|
|
const Standard_Real t0, const Standard_Real t1,
|
|
const Standard_Boolean SeqOrder,
|
|
TopTools_SequenceOfShape& S)
|
|
|
|
{
|
|
S.Clear();
|
|
Standard_Integer j, ndec=CutValues.Length();
|
|
Standard_Real first,last,m0,m1;
|
|
Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
|
|
|
|
TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
|
|
TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
|
|
TopExp::Vertices(CurrentEdge,Vf,Vl);
|
|
Vbid.Nullify();
|
|
|
|
if (SeqOrder) {
|
|
// from first to last
|
|
m0 = first;
|
|
V0 = Vf;
|
|
for (j=1; j<=ndec; j++) {
|
|
// piece of edge
|
|
m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
|
|
TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
|
|
CutE.Orientation(CurrentOrient);
|
|
S.Append(CutE);
|
|
m0 = m1;
|
|
V0 = TopExp::LastVertex(CutE);
|
|
if (j==ndec) {
|
|
// last piece
|
|
TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
|
|
LastE.Orientation(CurrentOrient);
|
|
S.Append(LastE);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// from last to first
|
|
m1 = last;
|
|
V1 = Vl;
|
|
for (j=ndec; j>=1; j--) {
|
|
// piece of edge
|
|
m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
|
|
TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
|
|
CutE.Orientation(CurrentOrient);
|
|
S.Append(CutE);
|
|
m1 = m0;
|
|
V1 = TopExp::FirstVertex(CutE);
|
|
if (j==1) {
|
|
// last piece
|
|
TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
|
|
LastE.Orientation(CurrentOrient);
|
|
S.Append(LastE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Face
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopoDS_Face BRepFill::Face(const TopoDS_Edge& Edge1,
|
|
const TopoDS_Edge& Edge2 )
|
|
{
|
|
TopoDS_Face Face;
|
|
|
|
BRep_Builder B;
|
|
// Class BRep_Tool without fields and without Constructor :
|
|
// BRep_Tool BT;
|
|
|
|
TopLoc_Location L,L1,L2;
|
|
Standard_Real f1,f2,l1,l2, Tol;
|
|
|
|
// Handle(Geom_Curve) C1 = BT.Curve(Edge1,L1,f1,l1);
|
|
Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
|
|
// Handle(Geom_Curve) C2 = BT.Curve(Edge2,L2,f2,l2);
|
|
Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
|
|
|
|
// compute the location
|
|
Standard_Boolean SameLoc = Standard_False;
|
|
if (L1 == L2) {
|
|
L = L1;
|
|
L1 = L2 = TopLoc_Location();
|
|
SameLoc = Standard_True;
|
|
}
|
|
|
|
// transform and trim the curves
|
|
|
|
TopoDS_Vertex V1f,V1l,V2f,V2l;
|
|
|
|
// create a new Handle
|
|
if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
|
|
Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) {
|
|
C1 = new Geom_TrimmedCurve(C1,f1,l1);
|
|
}
|
|
else {
|
|
C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
|
|
}
|
|
// eventually the curve is concerned
|
|
if ( !SameLoc) {
|
|
C1->Transform(L1.Transformation());
|
|
}
|
|
// it is set in the proper direction and its vertices are taken
|
|
if (Edge1.Orientation() == TopAbs_REVERSED) {
|
|
TopExp::Vertices(Edge1,V1l,V1f);
|
|
C1->Reverse();
|
|
}
|
|
else {
|
|
TopExp::Vertices(Edge1,V1f,V1l);
|
|
}
|
|
|
|
// a new Handle is created
|
|
if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
|
|
Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) {
|
|
C2 = new Geom_TrimmedCurve(C2,f2,l2);
|
|
}
|
|
else {
|
|
C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
|
|
}
|
|
// eventually the curve is concerned
|
|
if ( !SameLoc) {
|
|
C2->Transform(L2.Transformation());
|
|
}
|
|
// it is set in the proper direction and its vertices are taken
|
|
if (Edge2.Orientation() == TopAbs_REVERSED) {
|
|
TopExp::Vertices(Edge2,V2l,V2f);
|
|
C2->Reverse();
|
|
}
|
|
else {
|
|
TopExp::Vertices(Edge2,V2f,V2l);
|
|
}
|
|
|
|
// Are they closed edges?
|
|
Standard_Boolean Closed = V1f.IsSame(V1l) && V2f.IsSame(V2l);
|
|
|
|
|
|
GeomFill_Generator Generator;
|
|
Generator.AddCurve( C1);
|
|
Generator.AddCurve( C2);
|
|
Generator.Perform( Precision::PConfusion());
|
|
|
|
Handle(Geom_Surface) Surf = Generator.Surface();
|
|
Handle(Geom_Curve) Iso;
|
|
|
|
B.MakeFace(Face,Surf,Precision::Confusion());
|
|
|
|
// make the missing edges
|
|
Surf->Bounds(f1,l1,f2,l2);
|
|
|
|
TopoDS_Edge Edge3, Edge4;
|
|
|
|
Iso = Surf->UIso(f1);
|
|
Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
|
|
if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
|
|
B.MakeEdge(Edge3,Iso,Precision::Confusion());
|
|
}
|
|
else {
|
|
B.MakeEdge(Edge3);
|
|
B.Degenerated(Edge3, Standard_True);
|
|
}
|
|
V1f.Orientation(TopAbs_FORWARD);
|
|
B.Add(Edge3,V1f);
|
|
V2f.Orientation(TopAbs_REVERSED);
|
|
B.Add(Edge3,V2f);
|
|
B.Range(Edge3,f2,l2);
|
|
|
|
if (Closed) {
|
|
Edge4 = Edge3;
|
|
}
|
|
else {
|
|
Iso = Surf->UIso(l1);
|
|
Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
|
|
if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
|
|
B.MakeEdge(Edge4,Iso,Precision::Confusion());
|
|
}
|
|
else {
|
|
B.MakeEdge(Edge4);
|
|
B.Degenerated(Edge4, Standard_True);
|
|
}
|
|
V1l.Orientation(TopAbs_FORWARD);
|
|
B.Add(Edge4,V1l);
|
|
V2l.Orientation(TopAbs_REVERSED);
|
|
B.Add(Edge4,V2l);
|
|
B.Range(Edge4,f2,l2);
|
|
}
|
|
|
|
// make the wire
|
|
|
|
TopoDS_Wire W;
|
|
B.MakeWire(W);
|
|
|
|
Edge3.Reverse();
|
|
B.Add(W,Edge1);
|
|
B.Add(W,Edge4);
|
|
B.Add(W,Edge2.Reversed());
|
|
B.Add(W,Edge3);
|
|
W.Closed (Standard_True);
|
|
|
|
B.Add(Face,W);
|
|
|
|
// set the pcurves
|
|
|
|
Standard_Real T = Precision::Confusion();
|
|
|
|
if ( Edge1.Orientation() == TopAbs_REVERSED ) {
|
|
B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),Face,T);
|
|
B.Range(Edge1,Face,-l1,-f1);
|
|
}
|
|
else {
|
|
B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),Face,T);
|
|
B.Range(Edge1,Face,f1,l1);
|
|
}
|
|
|
|
if ( Edge2.Orientation() == TopAbs_REVERSED ) {
|
|
B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),Face,T);
|
|
B.Range(Edge2,Face,-l1,-f1);
|
|
}
|
|
else {
|
|
B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),Face,T);
|
|
B.Range(Edge2,Face,f1,l1);
|
|
}
|
|
|
|
if ( Closed) {
|
|
B.UpdateEdge(Edge3,
|
|
new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
|
|
new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
|
|
}
|
|
else {
|
|
B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
|
|
B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
|
|
}
|
|
|
|
// Set the non parameter flag;
|
|
B.SameParameter(Edge1,Standard_False);
|
|
B.SameParameter(Edge2,Standard_False);
|
|
B.SameParameter(Edge3,Standard_False);
|
|
B.SameParameter(Edge4,Standard_False);
|
|
B.SameRange(Edge1,Standard_False);
|
|
B.SameRange(Edge2,Standard_False);
|
|
B.SameRange(Edge3,Standard_False);
|
|
B.SameRange(Edge4,Standard_False);
|
|
|
|
BRepLib::SameParameter(Face);
|
|
|
|
if ( SameLoc) Face.Move(L);
|
|
return Face;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Shell
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopoDS_Shell BRepFill::Shell(const TopoDS_Wire& Wire1,
|
|
const TopoDS_Wire& Wire2 )
|
|
{
|
|
TopoDS_Shell Shell;
|
|
TopoDS_Face Face;
|
|
TopoDS_Shape S1, S2;
|
|
TopoDS_Edge Edge1, Edge2, Edge3, Edge4, Couture;
|
|
|
|
BRep_Builder B;
|
|
// Class BRep_Tool without fields and without Constructor :
|
|
// BRep_Tool BT;
|
|
B.MakeShell(Shell);
|
|
|
|
TopExp_Explorer ex1;
|
|
TopExp_Explorer ex2;
|
|
|
|
Standard_Boolean Closed = Wire1.Closed() && Wire2.Closed();
|
|
|
|
Standard_Boolean thefirst = Standard_True;
|
|
|
|
ex1.Init(Wire1,TopAbs_EDGE);
|
|
ex2.Init(Wire2,TopAbs_EDGE);
|
|
|
|
while ( ex1.More() && ex2.More() ) {
|
|
|
|
Edge1 = TopoDS::Edge(ex1.Current());
|
|
Edge2 = TopoDS::Edge(ex2.Current());
|
|
|
|
Standard_Boolean Periodic =
|
|
BRep_Tool::IsClosed(Edge1) && BRep_Tool::IsClosed(Edge2);
|
|
|
|
ex1.Next();
|
|
ex2.Next();
|
|
|
|
TopLoc_Location L,L1,L2;
|
|
Standard_Real f1,l1,f2,l2,Tol;
|
|
|
|
Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
|
|
Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
|
|
|
|
// compute the location
|
|
Standard_Boolean SameLoc = Standard_False;
|
|
if (L1 == L2) {
|
|
L = L1;
|
|
L1 = L2 = TopLoc_Location();
|
|
SameLoc = Standard_True;
|
|
}
|
|
|
|
// transform and trim the curves
|
|
|
|
TopoDS_Vertex V1f,V1l,V2f,V2l;
|
|
|
|
|
|
if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
|
|
Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) {
|
|
C1 = new Geom_TrimmedCurve(C1,f1,l1);
|
|
}
|
|
else {
|
|
C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
|
|
}
|
|
if ( !SameLoc) {
|
|
C1->Transform(L1.Transformation());
|
|
}
|
|
if (Edge1.Orientation() == TopAbs_REVERSED) {
|
|
TopExp::Vertices(Edge1,V1l,V1f);
|
|
C1->Reverse();
|
|
}
|
|
else
|
|
TopExp::Vertices(Edge1,V1f,V1l);
|
|
|
|
if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
|
|
Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) {
|
|
C2 = new Geom_TrimmedCurve(C2,f2,l2);
|
|
}
|
|
else {
|
|
C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
|
|
}
|
|
if ( !SameLoc) {
|
|
C2->Transform(L2.Transformation());
|
|
}
|
|
if (Edge2.Orientation() == TopAbs_REVERSED) {
|
|
TopExp::Vertices(Edge2,V2l,V2f);
|
|
C2->Reverse();
|
|
}
|
|
else
|
|
TopExp::Vertices(Edge2,V2f,V2l);
|
|
|
|
GeomFill_Generator Generator;
|
|
Generator.AddCurve( C1);
|
|
Generator.AddCurve( C2);
|
|
Generator.Perform( Precision::PConfusion());
|
|
|
|
Handle(Geom_Surface) Surf = Generator.Surface();
|
|
Handle(Geom_Curve) Iso;
|
|
|
|
B.MakeFace(Face,Surf,Precision::Confusion());
|
|
|
|
// make the missing edges
|
|
Surf->Bounds(f1,l1,f2,l2);
|
|
|
|
if ( thefirst) {
|
|
Iso = Surf->UIso(f1);
|
|
// Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f));
|
|
Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
|
|
if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
|
|
B.MakeEdge(Edge3,Iso,Precision::Confusion());
|
|
}
|
|
else {
|
|
B.MakeEdge(Edge3);
|
|
B.Degenerated(Edge3, Standard_True);
|
|
}
|
|
V1f.Orientation(TopAbs_FORWARD);
|
|
B.Add(Edge3,V1f);
|
|
V2f.Orientation(TopAbs_REVERSED);
|
|
B.Add(Edge3,V2f);
|
|
B.Range(Edge3,f2,l2);
|
|
if ( Closed) {
|
|
Couture = Edge3;
|
|
}
|
|
Edge3.Reverse();
|
|
thefirst = Standard_False;
|
|
}
|
|
else {
|
|
Edge3 = Edge4;
|
|
Edge3.Reverse();
|
|
}
|
|
|
|
if ( Closed && !ex1.More() && !ex2.More() ) {
|
|
Edge4 = Couture;
|
|
}
|
|
else {
|
|
Iso = Surf->UIso(l1);
|
|
// Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
|
|
Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
|
|
if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
|
|
B.MakeEdge(Edge4,Iso,Precision::Confusion());
|
|
}
|
|
else {
|
|
B.MakeEdge(Edge4);
|
|
B.Degenerated(Edge4, Standard_True);
|
|
}
|
|
V1l.Orientation(TopAbs_FORWARD);
|
|
B.Add(Edge4,V1l);
|
|
V2l.Orientation(TopAbs_REVERSED);
|
|
B.Add(Edge4,V2l);
|
|
B.Range(Edge4,f2,l2);
|
|
}
|
|
|
|
// make the wire
|
|
|
|
TopoDS_Wire W;
|
|
B.MakeWire(W);
|
|
|
|
B.Add(W,Edge1);
|
|
B.Add(W,Edge4);
|
|
B.Add(W,Edge2.Reversed());
|
|
B.Add(W,Edge3);
|
|
W.Closed (Standard_True);
|
|
|
|
B.Add(Face,W);
|
|
|
|
if ( SameLoc) Face.Move( L);
|
|
|
|
B.Add(Shell,Face);
|
|
|
|
// set the pcurves
|
|
|
|
Standard_Real T = Precision::Confusion();
|
|
|
|
if ( Edge1.Orientation() == TopAbs_REVERSED ) {
|
|
B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
|
|
Face,T);
|
|
B.Range(Edge1,Face,-l1,-f1);
|
|
}
|
|
else {
|
|
B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
|
|
Face,T);
|
|
B.Range(Edge1,Face,f1,l1);
|
|
}
|
|
|
|
if ( Edge2.Orientation() == TopAbs_REVERSED ) {
|
|
B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
|
|
Face,T);
|
|
B.Range(Edge2,Face,-l1,-f1);
|
|
}
|
|
else {
|
|
B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
|
|
Face,T);
|
|
B.Range(Edge2,Face,f1,l1);
|
|
}
|
|
|
|
if ( Periodic) {
|
|
B.UpdateEdge(Edge3,
|
|
new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
|
|
new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
|
|
Face,T);
|
|
}
|
|
else {
|
|
B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
|
|
B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
|
|
}
|
|
|
|
// Set the non parameter flag;
|
|
B.SameParameter(Edge1,Standard_False);
|
|
B.SameParameter(Edge2,Standard_False);
|
|
B.SameParameter(Edge3,Standard_False);
|
|
B.SameParameter(Edge4,Standard_False);
|
|
B.SameRange(Edge1,Standard_False);
|
|
B.SameRange(Edge2,Standard_False);
|
|
B.SameRange(Edge3,Standard_False);
|
|
B.SameRange(Edge4,Standard_False);
|
|
}
|
|
|
|
Shell.Closed (BRep_Tool::IsClosed (Shell));
|
|
BRepLib::SameParameter(Shell);
|
|
return Shell;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Axe
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepFill::Axe (const TopoDS_Shape& Spine,
|
|
const TopoDS_Wire& Profile,
|
|
gp_Ax3& AxeProf,
|
|
Standard_Boolean& ProfOnSpine,
|
|
const Standard_Real Tol)
|
|
{
|
|
gp_Pnt Loc,Loc1,Loc2;
|
|
gp_Vec Tang,Tang1,Tang2,Normal;
|
|
|
|
Handle(Geom_Surface) S;
|
|
TopLoc_Location L;
|
|
|
|
TopoDS_Face aFace;
|
|
|
|
// normal to the Spine.
|
|
if (Spine.ShapeType() == TopAbs_FACE) {
|
|
aFace = TopoDS::Face(Spine);
|
|
S = BRep_Tool::Surface(TopoDS::Face(Spine), L);
|
|
if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) {
|
|
BRepLib_FindSurface FS(TopoDS::Face(Spine), -1, Standard_True);
|
|
if ( FS.Found()) {
|
|
S = FS.Surface();
|
|
L = FS.Location();
|
|
}
|
|
else {
|
|
throw Standard_NoSuchObject("BRepFill_Evolved : The Face is not planar");
|
|
}
|
|
}
|
|
}
|
|
else if (Spine.ShapeType() == TopAbs_WIRE) {
|
|
aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True);
|
|
S = BRep_Tool::Surface(aFace, L);
|
|
}
|
|
|
|
if (S.IsNull()) throw Standard_DomainError("BRepFill_Evolved::Axe");
|
|
|
|
if (!L.IsIdentity())
|
|
S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
|
|
|
|
Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction();
|
|
|
|
// Find vertex of the profile closest to the spine.
|
|
Standard_Real DistMin = Precision::Infinite();
|
|
Standard_Real Dist;
|
|
// Standard_Real Tol2 = Tol*Tol;
|
|
Standard_Real Tol2 = 1.e-10;
|
|
TopExp_Explorer PE, SE;
|
|
BRepExtrema_ExtPC BE;
|
|
Standard_Real Par =0.,f,l;
|
|
// Standard_Real D1,D2;
|
|
gp_Pnt P1,P2;
|
|
|
|
// First check if there is contact Vertex Vertex.
|
|
Standard_Boolean IsOnVertex = Standard_False;
|
|
SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
|
|
// modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___
|
|
// for (;SE.More() && !IsOnVertex ; SE.Next()) {
|
|
for (;SE.More(); SE.Next()) {
|
|
P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current()));
|
|
|
|
PE.Init(Profile,TopAbs_VERTEX);
|
|
for ( ; PE.More(); PE.Next()) {
|
|
P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current()));
|
|
Standard_Real DistP1P2 = P1.SquareDistance(P2);
|
|
IsOnVertex = (DistP1P2 <= Tol2);
|
|
if (IsOnVertex) break;
|
|
}
|
|
// otherwise SE.Next() is done and VonF is wrong
|
|
if (IsOnVertex) break;
|
|
// modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___
|
|
}
|
|
|
|
if (IsOnVertex) {
|
|
// try to find on which edge which shared this vertex,
|
|
// the profile must be considered.
|
|
// E1, E2 : those two edges.
|
|
TopTools_IndexedDataMapOfShapeListOfShape Map;
|
|
TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD),
|
|
TopAbs_VERTEX,
|
|
TopAbs_EDGE,
|
|
Map);
|
|
|
|
const TopoDS_Vertex& VonF = TopoDS::Vertex(SE.Current());
|
|
const TopTools_ListOfShape& List = Map.FindFromKey(VonF);
|
|
const TopoDS_Edge& E1 = TopoDS::Edge(List.First());
|
|
const TopoDS_Edge& E2 = TopoDS::Edge(List. Last());
|
|
|
|
Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l);
|
|
Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace);
|
|
CE1->D1(Par1,Loc1,Tang1);
|
|
if (!L.IsIdentity()) {
|
|
Tang1.Transform(L.Transformation());
|
|
Loc1.Transform(L.Transformation());
|
|
}
|
|
if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse();
|
|
|
|
Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l);
|
|
Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace);
|
|
CE2->D1(Par2,Loc2,Tang2);
|
|
if (!L.IsIdentity()) {
|
|
Tang2.Transform(L.Transformation());
|
|
Loc2.Transform(L.Transformation());
|
|
}
|
|
if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse();
|
|
|
|
// modified by NIZHNY-EAP Wed Feb 2 15:38:41 2000 ___BEGIN___
|
|
Tang1.Normalize();
|
|
Tang2.Normalize();
|
|
Standard_Real sca1=0., sca2=0.;
|
|
TopoDS_Vertex V1, V2;
|
|
TopoDS_Edge E;
|
|
for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) {
|
|
E = TopoDS::Edge(PE.Current());
|
|
TopExp::Vertices(E, V1, V2);
|
|
P1 = BRep_Tool::Pnt(V1);
|
|
P2 = BRep_Tool::Pnt(V2);
|
|
gp_Vec vec(P1,P2);
|
|
sca1 += Abs(Tang1.Dot(vec));
|
|
sca2 += Abs(Tang2.Dot(vec));
|
|
}
|
|
// modified by NIZHNY-EAP Wed Feb 2 15:38:44 2000 ___END___
|
|
|
|
if ( Abs(sca1) < Abs(sca2)) {
|
|
Loc = Loc1;
|
|
Tang = Tang1;
|
|
}
|
|
else {
|
|
Loc = Loc2;
|
|
Tang = Tang2;
|
|
}
|
|
DistMin = 0.;
|
|
}
|
|
else {
|
|
SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
|
|
for ( ; SE.More(); SE.Next()) {
|
|
const TopoDS_Edge& E = TopoDS::Edge(SE.Current());
|
|
BE.Initialize(E);
|
|
for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) {
|
|
Dist = Precision::Infinite();
|
|
const TopoDS_Vertex& V = TopoDS::Vertex(PE.Current());
|
|
BE.Perform(V);
|
|
if (BE.IsDone()) {
|
|
// extrema.
|
|
for (Standard_Integer i = 1; i <= BE.NbExt(); i++) {
|
|
if (BE.IsMin(i)) {
|
|
Dist = sqrt (BE.SquareDistance(i));
|
|
Par = BE.Parameter(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// save minimum.
|
|
if (Dist < DistMin) {
|
|
DistMin = Dist;
|
|
BRepAdaptor_Curve BAC(E);
|
|
BAC.D1 (Par,Loc,Tang);
|
|
if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ProfOnSpine = (DistMin < Tol);
|
|
//Construction AxeProf;
|
|
gp_Ax3 A3 (Loc,Normal,Tang);
|
|
AxeProf = A3;
|
|
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SearchOrigin
|
|
//purpose : Cut and orientate a closed wire.
|
|
//=======================================================================
|
|
|
|
void BRepFill::SearchOrigin(TopoDS_Wire & W,
|
|
const gp_Pnt& P,
|
|
const gp_Vec& Dir,
|
|
const Standard_Real Tol)
|
|
{
|
|
if (!W.Closed())
|
|
Standard_NoSuchObject::
|
|
Raise("BRepFill::SearchOrigin : the wire must be closed");
|
|
|
|
|
|
Standard_Boolean NewVertex = Standard_False;
|
|
Standard_Real theparam = 1.e101, angle;
|
|
TopoDS_Vertex V ;
|
|
TopoDS_Edge E, Eref;
|
|
BRep_Builder B;
|
|
// Class BRep_Tool without fields and without Constructor :
|
|
// BRep_Tool BT;
|
|
|
|
W.Orientation(TopAbs_FORWARD); //to avoid composing the orientations
|
|
|
|
// Calculate the distance
|
|
B.MakeVertex(V, P, Tol);
|
|
BRepExtrema_DistShapeShape DSS(V, W);
|
|
if (DSS.IsDone()) {
|
|
Standard_Integer isol = 1;
|
|
Standard_Real dss = P.Distance(DSS.PointOnShape2(isol));
|
|
for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++)
|
|
if (dss > P.Distance(DSS.PointOnShape2(iss))) {
|
|
dss = P.Distance(DSS.PointOnShape2(iss));
|
|
isol = iss;
|
|
}
|
|
TopoDS_Shape supp = DSS.SupportOnShape2(isol);
|
|
if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) {
|
|
V = TopoDS::Vertex(supp);
|
|
}
|
|
else {
|
|
TopoDS_Vertex Vf, Vl;
|
|
Standard_Real d, dist;
|
|
E = TopoDS::Edge(supp);
|
|
TopExp::Vertices(E, Vf, Vl);
|
|
// dist = P.Distance(BT.Pnt(Vf));
|
|
dist = P.Distance(BRep_Tool::Pnt(Vf));
|
|
if (dist < Tol) {
|
|
V = Vl;
|
|
}
|
|
// d = P.Distance(BT.Pnt(Vl));
|
|
d = P.Distance(BRep_Tool::Pnt(Vl));
|
|
if ((d<Tol) && (d<dist)) {
|
|
V = Vf;
|
|
dist = d;
|
|
}
|
|
NewVertex = (dist > Tol);
|
|
if (NewVertex) {
|
|
DSS.ParOnEdgeS2(isol, theparam);
|
|
}
|
|
}
|
|
}
|
|
#ifdef OCCT_DEBUG
|
|
else {
|
|
std::cout << "BRepFill::SearchOrigine : Echec Distance" << std::endl;
|
|
}
|
|
#endif
|
|
|
|
Standard_Integer ii, rangdeb=0, NbEdges=0;
|
|
Standard_Boolean forward;
|
|
BRepTools_WireExplorer exp;
|
|
|
|
// Calculate the number of edges
|
|
for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
|
|
if (NewVertex) {
|
|
NbEdges++;
|
|
Eref = E;
|
|
}
|
|
|
|
// Construct the Table and calculate rangdeb
|
|
TopTools_Array1OfShape Edges(1, NbEdges);
|
|
for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) {
|
|
E = exp.Current();
|
|
if (NewVertex && E.IsSame(Eref)) {
|
|
TopoDS_Edge E1, E2;
|
|
CutEdge(E, theparam, E1, E2, exp.CurrentVertex());
|
|
Edges(ii) = E1;
|
|
ii++;
|
|
Edges(ii) = E2;
|
|
rangdeb = ii;
|
|
}
|
|
else {
|
|
Edges(ii) = E;
|
|
}
|
|
if (!NewVertex && V.IsSame(exp.CurrentVertex())) {
|
|
rangdeb = ii;
|
|
}
|
|
}
|
|
if (rangdeb == 0) rangdeb = NbEdges;
|
|
|
|
// Calculate the direction of parsing
|
|
E = TopoDS::Edge(Edges(rangdeb));
|
|
if (!NewVertex) {
|
|
// theparam = BT.Parameter(V, E);
|
|
theparam = BRep_Tool::Parameter(V, E);
|
|
}
|
|
BRepAdaptor_Curve AC(E);
|
|
gp_Pnt Pe;
|
|
gp_Vec Ve;
|
|
AC.D1(theparam, Pe, Ve);
|
|
if (E.Orientation()==TopAbs_REVERSED) {
|
|
Ve *= -1;
|
|
}
|
|
angle = Ve.Angle(Dir);
|
|
if (angle > M_PI) angle = 2*M_PI - angle;
|
|
forward = (angle <= M_PI/2);
|
|
|
|
// Reconstruction
|
|
MakeWire( Edges, rangdeb, forward, W);
|
|
W.Closed(Standard_True);
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : ComputeACR
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepFill::ComputeACR(const TopoDS_Wire& wire,
|
|
TColStd_Array1OfReal& ACR)
|
|
{
|
|
// calculate the reduced curvilinear abscisses and the length of the wire
|
|
BRepTools_WireExplorer anExp;
|
|
Standard_Integer nbEdges=0, i;
|
|
|
|
// cumulated lengths
|
|
ACR.Init(0);
|
|
for(anExp.Init(wire); anExp.More(); anExp.Next()) {
|
|
nbEdges++;
|
|
TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
|
|
ACR(nbEdges) = ACR(nbEdges-1);
|
|
if (!BRep_Tool::Degenerated(Ecur)) {
|
|
BRepAdaptor_Curve anEcur(Ecur);
|
|
ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur);
|
|
}
|
|
}
|
|
|
|
// total length of the wire
|
|
ACR(0) = ACR(nbEdges);
|
|
|
|
// reduced curvilinear abscisses
|
|
if (ACR(0)>Precision::Confusion()) {
|
|
for (i=1; i<=nbEdges; i++) {
|
|
ACR(i) /= ACR(0);
|
|
}
|
|
}
|
|
else {
|
|
// punctual wire
|
|
ACR(nbEdges) = 1;
|
|
}
|
|
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : InsertACR
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire,
|
|
const TColStd_Array1OfReal& ACRcuts,
|
|
const Standard_Real prec)
|
|
{
|
|
// calculate ACR of the wire to be cut
|
|
BRepTools_WireExplorer anExp;
|
|
Standard_Integer nbEdges=0;
|
|
for(anExp.Init(wire); anExp.More(); anExp.Next()) {
|
|
nbEdges++;
|
|
}
|
|
TColStd_Array1OfReal ACRwire(0,nbEdges);
|
|
ComputeACR(wire, ACRwire);
|
|
|
|
Standard_Integer i, j, nmax=ACRcuts.Length();
|
|
TColStd_Array1OfReal paradec(1,nmax);
|
|
BRepLib_MakeWire MW;
|
|
|
|
Standard_Real t0,t1=0;
|
|
nbEdges=0;
|
|
|
|
// processing edge by edge
|
|
for(anExp.Init(wire); anExp.More(); anExp.Next()) {
|
|
nbEdges++;
|
|
t0 = t1;
|
|
t1 = ACRwire(nbEdges);
|
|
|
|
// parameters of cut on this edge
|
|
Standard_Integer ndec=0;
|
|
for (i=1; i<=ACRcuts.Length(); i++ ) {
|
|
if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) {
|
|
ndec++;
|
|
paradec(ndec) = ACRcuts(i);
|
|
}
|
|
}
|
|
|
|
TopoDS_Edge E = anExp.Current();
|
|
TopoDS_Vertex V = anExp.CurrentVertex();
|
|
|
|
if (ndec==0 || BRep_Tool::Degenerated(E)) {
|
|
// copy the edge
|
|
MW.Add(E);
|
|
}
|
|
else {
|
|
// it is necessary to cut the edge
|
|
// following the direction of parsing of the wire
|
|
Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
|
|
TopTools_SequenceOfShape SE;
|
|
SE.Clear();
|
|
TColStd_SequenceOfReal SR;
|
|
SR.Clear();
|
|
// the wire is always FORWARD
|
|
// it is necessary to modify the parameter of cut6 if the edge is REVERSED
|
|
if (E.Orientation() == TopAbs_FORWARD) {
|
|
for (j=1; j<=ndec; j++) SR.Append(paradec(j));
|
|
}
|
|
else {
|
|
for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j));
|
|
}
|
|
TrimEdge(E,SR,t0,t1,SO,SE);
|
|
for (j=1; j<=SE.Length(); j++) {
|
|
MW.Add(TopoDS::Edge(SE.Value(j)));
|
|
}
|
|
}
|
|
}
|
|
|
|
// result
|
|
TopAbs_Orientation Orien = wire.Orientation();
|
|
TopoDS_Shape aLocalShape = MW.Wire();
|
|
aLocalShape.Orientation(Orien);
|
|
TopoDS_Wire wres = TopoDS::Wire(aLocalShape);
|
|
// TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien));
|
|
return wres;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|