mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-08-04 04:16:02 +08:00
50314b6938
- free bounds should be built from boundary edges only - ignore edges with INTERNAL and EXTERNAL orientation in ConnectEdgesToWires()
689 lines
21 KiB
C++
689 lines
21 KiB
C++
// Created on: 1998-04-27
|
|
// Created by: Roman LYGIN
|
|
// Copyright (c) 1998-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: Thu Sep 17 12:27:58 1998
|
|
// 25.12.98 pdn transmission from BRepTools_Sewing to BRepBuilderAPI_Sewing
|
|
// szv#4 S4163
|
|
// 11.01.00 svv #1: porting on DEC
|
|
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRep_Tool.hxx>
|
|
#include <BRepBuilderAPI_Sewing.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <NCollection_UBTreeFiller.hxx>
|
|
#include <Precision.hxx>
|
|
#include <ShapeAnalysis.hxx>
|
|
#include <ShapeAnalysis_BoxBndTree.hxx>
|
|
#include <ShapeAnalysis_Edge.hxx>
|
|
#include <ShapeAnalysis_FreeBounds.hxx>
|
|
#include <ShapeAnalysis_Shell.hxx>
|
|
#include <ShapeAnalysis_Wire.hxx>
|
|
#include <ShapeBuild_Edge.hxx>
|
|
#include <ShapeBuild_Vertex.hxx>
|
|
#include <ShapeExtend_Explorer.hxx>
|
|
#include <ShapeExtend_WireData.hxx>
|
|
#include <NCollection_Array1.hxx>
|
|
#include <NCollection_LinearVector.hxx>
|
|
#include <Standard_Integer.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_Compound.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Iterator.hxx>
|
|
#include <TopoDS_Shape.hxx>
|
|
#include <TopoDS_Shell.hxx>
|
|
#include <TopoDS_Vertex.hxx>
|
|
#include <TopoDS_Wire.hxx>
|
|
#include <NCollection_HArray1.hxx>
|
|
#include <TopTools_ShapeMapHasher.hxx>
|
|
|
|
// ied_modif_for_compil_Nov-19-1998
|
|
//=================================================================================================
|
|
|
|
ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds() = default;
|
|
|
|
//=================================================================================================
|
|
|
|
ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape,
|
|
const double toler,
|
|
const bool splitclosed,
|
|
const bool splitopen)
|
|
: myTolerance(toler),
|
|
myShared(false),
|
|
mySplitClosed(splitclosed),
|
|
mySplitOpen(splitopen)
|
|
{
|
|
BRepBuilderAPI_Sewing Sew(toler, false, false);
|
|
for (TopoDS_Iterator S(shape); S.More(); S.Next())
|
|
{
|
|
Sew.Add(S.Value());
|
|
}
|
|
Sew.Perform();
|
|
//
|
|
// Extract free edges.
|
|
//
|
|
int nbedge = Sew.NbFreeEdges();
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> edges = new NCollection_HSequence<TopoDS_Shape>;
|
|
TopoDS_Edge anEdge;
|
|
for (int iedge = 1; iedge <= nbedge; iedge++)
|
|
{
|
|
anEdge = TopoDS::Edge(Sew.FreeEdge(iedge));
|
|
if (!BRep_Tool::Degenerated(anEdge))
|
|
{
|
|
edges->Append(anEdge);
|
|
}
|
|
}
|
|
//
|
|
// Chainage.
|
|
//
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> wires = ConnectEdgesToWires(edges, toler, false);
|
|
DispatchWires(wires, myWires, myEdges);
|
|
SplitWires();
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape,
|
|
const bool splitclosed,
|
|
const bool splitopen,
|
|
const bool checkinternaledges)
|
|
: myTolerance(0.),
|
|
myShared(true),
|
|
mySplitClosed(splitclosed),
|
|
mySplitOpen(splitopen)
|
|
{
|
|
TopoDS_Shell aTmpShell;
|
|
BRep_Builder aB;
|
|
aB.MakeShell(aTmpShell);
|
|
for (TopExp_Explorer aExpFace(shape, TopAbs_FACE); aExpFace.More(); aExpFace.Next())
|
|
{
|
|
aB.Add(aTmpShell, aExpFace.Current());
|
|
}
|
|
|
|
ShapeAnalysis_Shell sas;
|
|
sas.CheckOrientedShells(aTmpShell, true, checkinternaledges);
|
|
|
|
if (sas.HasFreeEdges())
|
|
{
|
|
ShapeExtend_Explorer see;
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> edges =
|
|
see.SeqFromCompound(sas.FreeEdges(), false);
|
|
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> wires =
|
|
ConnectEdgesToWires(edges, Precision::Confusion(), true);
|
|
DispatchWires(wires, myWires, myEdges);
|
|
SplitWires();
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> ShapeAnalysis_FreeBounds::ConnectEdgesToWires(
|
|
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& edges,
|
|
const double toler,
|
|
const bool shared)
|
|
{
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> iwires = new NCollection_HSequence<TopoDS_Shape>;
|
|
NCollection_LinearVector<int> anEdgeIndices;
|
|
BRep_Builder B;
|
|
|
|
int i; // svv #1
|
|
for (i = 1; i <= edges->Length(); i++)
|
|
{
|
|
const TopAbs_Orientation anOrientation = edges->Value(i).Orientation();
|
|
if (anOrientation == TopAbs_INTERNAL || anOrientation == TopAbs_EXTERNAL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
TopoDS_Wire wire;
|
|
B.MakeWire(wire);
|
|
B.Add(wire, edges->Value(i));
|
|
iwires->Append(wire);
|
|
anEdgeIndices.Append(i);
|
|
}
|
|
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> wires =
|
|
ConnectWiresToWires(iwires, toler, shared);
|
|
|
|
for (i = 1; i <= iwires->Length(); i++)
|
|
{
|
|
if (iwires->Value(i).Orientation() == TopAbs_REVERSED)
|
|
{
|
|
edges->ChangeValue(anEdgeIndices[i - 1]).Reverse();
|
|
}
|
|
}
|
|
|
|
return wires;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void ShapeAnalysis_FreeBounds::ConnectEdgesToWires(
|
|
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& edges,
|
|
const double toler,
|
|
const bool shared,
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>>& wires)
|
|
{
|
|
wires = ConnectEdgesToWires(edges, toler, shared);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> ShapeAnalysis_FreeBounds::ConnectWiresToWires(
|
|
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& iwires,
|
|
const double toler,
|
|
const bool shared)
|
|
{
|
|
NCollection_DataMap<TopoDS_Shape, TopoDS_Shape, TopTools_ShapeMapHasher> map;
|
|
return ConnectWiresToWires(iwires, toler, shared, map);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void ShapeAnalysis_FreeBounds::ConnectWiresToWires(
|
|
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& iwires,
|
|
const double toler,
|
|
const bool shared,
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>>& owires)
|
|
{
|
|
owires = ConnectWiresToWires(iwires, toler, shared);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static void connectWiresToWiresImpl(
|
|
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& iwires,
|
|
const double toler,
|
|
const bool shared,
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>>& owires,
|
|
NCollection_DataMap<TopoDS_Shape, TopoDS_Shape, TopTools_ShapeMapHasher>& vertices)
|
|
{
|
|
if (iwires.IsNull() || !iwires->Length())
|
|
{
|
|
owires = new NCollection_HSequence<TopoDS_Shape>; // was left null, later crashed Append
|
|
return;
|
|
}
|
|
occ::handle<NCollection_HArray1<TopoDS_Shape>> arrwires =
|
|
new NCollection_HArray1<TopoDS_Shape>(1, iwires->Length());
|
|
int i;
|
|
for (i = 1; i <= arrwires->Length(); i++)
|
|
{
|
|
arrwires->SetValue(i, iwires->Value(i));
|
|
}
|
|
owires = new NCollection_HSequence<TopoDS_Shape>;
|
|
double tolerance = std::max(toler, Precision::Confusion());
|
|
|
|
ShapeAnalysis_BoxBndTreeSelector aSel(arrwires, shared);
|
|
occ::handle<ShapeExtend_WireData> sewd;
|
|
for (i = 1; i <= arrwires->Length(); i++)
|
|
{
|
|
occ::handle<ShapeExtend_WireData> aWireData =
|
|
new ShapeExtend_WireData(TopoDS::Wire(arrwires->Value(i)));
|
|
if (aWireData->NbEdges() > 0)
|
|
{
|
|
if (sewd.IsNull())
|
|
{
|
|
sewd = aWireData;
|
|
aSel.LoadList(i);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (aWireData->NbNonManifoldEdges() > 0)
|
|
{
|
|
owires->Append(aWireData->Wire());
|
|
}
|
|
aSel.LoadList(i);
|
|
}
|
|
}
|
|
|
|
if (sewd.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
occ::handle<ShapeAnalysis_Wire> saw = new ShapeAnalysis_Wire;
|
|
saw->Load(sewd);
|
|
saw->SetPrecision(tolerance);
|
|
|
|
NCollection_UBTree<int, Bnd_Box> aBBTree;
|
|
NCollection_UBTreeFiller<int, Bnd_Box> aTreeFiller(aBBTree);
|
|
|
|
for (int inbW = 1; inbW <= arrwires->Length(); inbW++)
|
|
{
|
|
if (aSel.ContWire(inbW))
|
|
{
|
|
continue;
|
|
}
|
|
TopoDS_Wire trW = TopoDS::Wire(arrwires->Value(inbW));
|
|
Bnd_Box aBox;
|
|
TopoDS_Vertex trV1, trV2;
|
|
ShapeAnalysis::FindBounds(trW, trV1, trV2);
|
|
gp_Pnt trP1 = BRep_Tool::Pnt(trV1);
|
|
gp_Pnt trP2 = BRep_Tool::Pnt(trV2);
|
|
aBox.Set(trP1);
|
|
aBox.Add(trP2);
|
|
aBox.SetGap(tolerance);
|
|
aTreeFiller.Add(inbW, aBox);
|
|
}
|
|
|
|
aTreeFiller.Fill();
|
|
int nsel;
|
|
|
|
ShapeAnalysis_Edge sae;
|
|
bool done = false;
|
|
|
|
while (!done)
|
|
{
|
|
bool found = false, tail = false, direct = false;
|
|
int lwire = 0;
|
|
aSel.SetStop();
|
|
Bnd_Box FVBox, LVBox;
|
|
TopoDS_Vertex Vf, Vl;
|
|
Vf = sae.FirstVertex(sewd->Edge(1));
|
|
Vl = sae.LastVertex(sewd->Edge(sewd->NbEdges()));
|
|
|
|
gp_Pnt pf, pl;
|
|
pf = BRep_Tool::Pnt(Vf);
|
|
pl = BRep_Tool::Pnt(Vl);
|
|
FVBox.Set(pf);
|
|
FVBox.SetGap(tolerance);
|
|
LVBox.Set(pl);
|
|
LVBox.SetGap(tolerance);
|
|
|
|
aSel.DefineBoxes(FVBox, LVBox);
|
|
|
|
if (shared)
|
|
{
|
|
aSel.DefineVertexes(Vf, Vl);
|
|
}
|
|
else
|
|
{
|
|
aSel.DefinePnt(pf, pl);
|
|
aSel.SetTolerance(tolerance);
|
|
}
|
|
|
|
nsel = aBBTree.Select(aSel);
|
|
|
|
if (nsel != 0 && !aSel.LastCheckStatus(ShapeExtend_FAIL))
|
|
{
|
|
found = true;
|
|
lwire = aSel.GetNb();
|
|
tail = aSel.LastCheckStatus(ShapeExtend_DONE1) || aSel.LastCheckStatus(ShapeExtend_DONE2);
|
|
direct = aSel.LastCheckStatus(ShapeExtend_DONE1) || aSel.LastCheckStatus(ShapeExtend_DONE3);
|
|
aSel.LoadList(lwire);
|
|
}
|
|
|
|
if (found)
|
|
{
|
|
if (!direct)
|
|
{
|
|
arrwires->ChangeValue(lwire).Reverse();
|
|
}
|
|
|
|
occ::handle<ShapeExtend_WireData> acurwd =
|
|
new ShapeExtend_WireData(TopoDS::Wire(arrwires->Value(lwire)), true, true);
|
|
if (!acurwd->NbEdges())
|
|
{
|
|
continue;
|
|
}
|
|
sewd->Add(acurwd, (tail ? 0 : 1));
|
|
}
|
|
else
|
|
{
|
|
for (i = 1; i <= saw->NbEdges(); i++)
|
|
{
|
|
if (saw->CheckConnected(i))
|
|
{
|
|
int n2 = i;
|
|
int n1 = (n2 > 1 ? n2 - 1 : saw->NbEdges());
|
|
TopoDS_Edge E1 = sewd->Edge(n1);
|
|
TopoDS_Edge E2 = sewd->Edge(n2);
|
|
|
|
TopoDS_Vertex Vprev, Vfol, V;
|
|
Vprev = sae.LastVertex(E1);
|
|
Vfol = sae.FirstVertex(E2);
|
|
|
|
if (saw->LastCheckStatus(ShapeExtend_DONE1))
|
|
{
|
|
V = Vprev;
|
|
}
|
|
else
|
|
{
|
|
ShapeBuild_Vertex sbv;
|
|
V = sbv.CombineVertex(Vprev, Vfol);
|
|
}
|
|
vertices.Bind(Vprev, V);
|
|
vertices.Bind(Vfol, V);
|
|
|
|
ShapeBuild_Edge sbe;
|
|
if (saw->NbEdges() < 2)
|
|
{
|
|
sewd->Set(sbe.CopyReplaceVertices(E2, V, V), n2);
|
|
}
|
|
else
|
|
{
|
|
sewd->Set(sbe.CopyReplaceVertices(E2, V, TopoDS_Vertex()), n2);
|
|
if (!saw->LastCheckStatus(ShapeExtend_DONE1))
|
|
{
|
|
sewd->Set(sbe.CopyReplaceVertices(E1, TopoDS_Vertex(), V), n1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TopoDS_Wire wire = sewd->Wire();
|
|
if (!saw->CheckConnected(1) && saw->LastCheckStatus(ShapeExtend_OK))
|
|
{
|
|
wire.Closed(true);
|
|
}
|
|
|
|
owires->Append(wire);
|
|
sewd->Clear();
|
|
|
|
lwire = -1;
|
|
for (i = 1; i <= arrwires->Length(); i++)
|
|
{
|
|
if (!aSel.ContWire(i))
|
|
{
|
|
sewd->Add(TopoDS::Wire(arrwires->Value(i)));
|
|
aSel.LoadList(i);
|
|
|
|
if (sewd->NbEdges() > 0)
|
|
{
|
|
lwire = i;
|
|
break;
|
|
}
|
|
sewd->Clear();
|
|
}
|
|
}
|
|
|
|
if (lwire == -1)
|
|
{
|
|
done = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 1; i <= iwires->Length(); i++)
|
|
{
|
|
iwires->SetValue(i, arrwires->Value(i));
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> ShapeAnalysis_FreeBounds::ConnectWiresToWires(
|
|
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& iwires,
|
|
const double toler,
|
|
const bool shared,
|
|
NCollection_DataMap<TopoDS_Shape, TopoDS_Shape, TopTools_ShapeMapHasher>& vertices)
|
|
{
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> owires;
|
|
connectWiresToWiresImpl(iwires, toler, shared, owires, vertices);
|
|
return owires;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void ShapeAnalysis_FreeBounds::ConnectWiresToWires(
|
|
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& iwires,
|
|
const double toler,
|
|
const bool shared,
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>>& owires,
|
|
NCollection_DataMap<TopoDS_Shape, TopoDS_Shape, TopTools_ShapeMapHasher>& vertices)
|
|
{
|
|
connectWiresToWiresImpl(iwires, toler, shared, owires, vertices);
|
|
}
|
|
|
|
static void SplitWire(const TopoDS_Wire& wire,
|
|
const double toler,
|
|
const bool shared,
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>>& closed,
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>>& open)
|
|
{
|
|
closed = new NCollection_HSequence<TopoDS_Shape>;
|
|
open = new NCollection_HSequence<TopoDS_Shape>;
|
|
double tolerance = std::max(toler, Precision::Confusion());
|
|
|
|
BRep_Builder B;
|
|
ShapeAnalysis_Edge sae;
|
|
|
|
occ::handle<ShapeExtend_WireData> sewd = new ShapeExtend_WireData(wire);
|
|
int nbedges = sewd->NbEdges();
|
|
|
|
// ConnectedEdgeSequence - list of indices of connected edges to build a wire
|
|
NCollection_Sequence<int> ces;
|
|
// statuses - array of flags describing the edge:
|
|
// 0-free, 1-in CES, 2-already in wire,
|
|
// 3-no closed wire can be produced starting at this edge
|
|
NCollection_Array1<int> statuses(1, nbedges);
|
|
statuses.Init(0);
|
|
|
|
// building closed wires
|
|
int i; // svv #1
|
|
for (i = 1; i <= nbedges; i++)
|
|
{
|
|
if (statuses.Value(i) == 0)
|
|
{
|
|
ces.Append(i);
|
|
statuses.SetValue(i, 1); // putting into CES
|
|
bool SearchBackward = true;
|
|
|
|
for (;;)
|
|
{
|
|
bool found;
|
|
TopoDS_Edge edge;
|
|
TopoDS_Vertex lvertex;
|
|
gp_Pnt lpoint;
|
|
|
|
// searching for connection in ces
|
|
if (SearchBackward)
|
|
{
|
|
SearchBackward = false;
|
|
found = false;
|
|
edge = sewd->Edge(ces.Last());
|
|
lvertex = sae.LastVertex(edge);
|
|
lpoint = BRep_Tool::Pnt(lvertex);
|
|
int j; // svv #1
|
|
for (j = ces.Length(); (j >= 1) && !found; j--)
|
|
{
|
|
TopoDS_Vertex fv = sae.FirstVertex(sewd->Edge(ces.Value(j)));
|
|
gp_Pnt fp = BRep_Tool::Pnt(fv);
|
|
if ((shared && lvertex.IsSame(fv)) || (!shared && lpoint.IsEqual(fp, tolerance)))
|
|
{
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
if (found)
|
|
{
|
|
j++; // because of decreasing last iteration
|
|
// making closed wire
|
|
TopoDS_Wire wire1;
|
|
B.MakeWire(wire1);
|
|
for (int cesindex = j; cesindex <= ces.Length(); cesindex++)
|
|
{
|
|
B.Add(wire1, sewd->Edge(ces.Value(cesindex)));
|
|
statuses.SetValue(ces.Value(cesindex), 2);
|
|
}
|
|
wire1.Closed(true);
|
|
closed->Append(wire1);
|
|
ces.Remove(j, ces.Length());
|
|
if (ces.IsEmpty())
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// searching for connection among free edges
|
|
found = false;
|
|
edge = sewd->Edge(ces.Last());
|
|
lvertex = sae.LastVertex(edge);
|
|
lpoint = BRep_Tool::Pnt(lvertex);
|
|
int j; // svv #1
|
|
for (j = 1; (j <= nbedges) && !found; j++)
|
|
{
|
|
if (statuses.Value(j) == 0)
|
|
{
|
|
TopoDS_Vertex fv = sae.FirstVertex(sewd->Edge(j));
|
|
gp_Pnt fp = BRep_Tool::Pnt(fv);
|
|
if ((shared && lvertex.IsSame(fv)) || (!shared && lpoint.IsEqual(fp, tolerance)))
|
|
{
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (found)
|
|
{
|
|
j--; // because of last iteration
|
|
ces.Append(j);
|
|
statuses.SetValue(j, 1); // putting into CES
|
|
SearchBackward = true;
|
|
continue;
|
|
}
|
|
|
|
// no edges found - mark the branch as open (use status 3)
|
|
statuses.SetValue(ces.Last(), 3);
|
|
ces.Remove(ces.Length());
|
|
if (ces.IsEmpty())
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// building open wires
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> edges = new NCollection_HSequence<TopoDS_Shape>;
|
|
for (i = 1; i <= nbedges; i++)
|
|
{
|
|
if (statuses.Value(i) != 2)
|
|
{
|
|
edges->Append(sewd->Edge(i));
|
|
}
|
|
}
|
|
|
|
open = ShapeAnalysis_FreeBounds::ConnectEdgesToWires(edges, toler, shared);
|
|
}
|
|
|
|
void ShapeAnalysis_FreeBounds::SplitWires(
|
|
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& wires,
|
|
const double toler,
|
|
const bool shared,
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>>& closed,
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>>& open)
|
|
{
|
|
closed = new NCollection_HSequence<TopoDS_Shape>;
|
|
open = new NCollection_HSequence<TopoDS_Shape>;
|
|
|
|
for (int i = 1; i <= wires->Length(); i++)
|
|
{
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> tmpclosed, tmpopen;
|
|
SplitWire(TopoDS::Wire(wires->Value(i)), toler, shared, tmpclosed, tmpopen);
|
|
closed->Append(tmpclosed);
|
|
open->Append(tmpopen);
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void ShapeAnalysis_FreeBounds::DispatchWires(
|
|
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& wires,
|
|
TopoDS_Compound& closed,
|
|
TopoDS_Compound& open)
|
|
{
|
|
BRep_Builder B;
|
|
if (closed.IsNull())
|
|
{
|
|
B.MakeCompound(closed);
|
|
}
|
|
if (open.IsNull())
|
|
{
|
|
B.MakeCompound(open);
|
|
}
|
|
if (wires.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (int iw = 1; iw <= wires->Length(); iw++)
|
|
{
|
|
if (wires->Value(iw).Closed())
|
|
{
|
|
B.Add(closed, wires->Value(iw));
|
|
}
|
|
else
|
|
{
|
|
B.Add(open, wires->Value(iw));
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : SplitWires
|
|
// purpose : Splits compounds of closed (myWires) and open (myEdges) wires
|
|
// into small closed wires according to fields mySplitClosed and
|
|
// mySplitOpen and rebuilds compounds
|
|
//=======================================================================
|
|
|
|
void ShapeAnalysis_FreeBounds::SplitWires()
|
|
{
|
|
if (!mySplitClosed && !mySplitOpen)
|
|
{
|
|
return; // nothing to do
|
|
}
|
|
|
|
ShapeExtend_Explorer see;
|
|
occ::handle<NCollection_HSequence<TopoDS_Shape>> closedwires, cw1, cw2, openwires, ow1, ow2;
|
|
closedwires = see.SeqFromCompound(myWires, false);
|
|
openwires = see.SeqFromCompound(myEdges, false);
|
|
|
|
if (mySplitClosed)
|
|
{
|
|
SplitWires(closedwires, myTolerance, myShared, cw1, ow1);
|
|
}
|
|
else
|
|
{
|
|
cw1 = closedwires;
|
|
ow1 = new NCollection_HSequence<TopoDS_Shape>;
|
|
}
|
|
|
|
if (mySplitOpen)
|
|
{
|
|
SplitWires(openwires, myTolerance, myShared, cw2, ow2);
|
|
}
|
|
else
|
|
{
|
|
cw2 = new NCollection_HSequence<TopoDS_Shape>;
|
|
ow2 = openwires;
|
|
}
|
|
|
|
closedwires = cw1;
|
|
closedwires->Append(cw2);
|
|
openwires = ow1;
|
|
openwires->Append(ow2);
|
|
|
|
// szv#4:S4163:12Mar99 SGI warns
|
|
TopoDS_Shape compWires = see.CompoundFromSeq(closedwires);
|
|
TopoDS_Shape compEdges = see.CompoundFromSeq(openwires);
|
|
myWires = TopoDS::Compound(compWires);
|
|
myEdges = TopoDS::Compound(compEdges);
|
|
}
|