Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// 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.
// szv#4 S4163
#include <BRep_Builder.hxx>
#include <ShapeExtend_Explorer.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Wire.hxx>
#include <NCollection_List.hxx>
//=================================================================================================
ShapeExtend_Explorer::ShapeExtend_Explorer() = default;
//=================================================================================================
TopoDS_Shape ShapeExtend_Explorer::CompoundFromSeq(
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& seqval) const
{
BRep_Builder B;
TopoDS_Compound C;
B.MakeCompound(C);
int i, n = seqval->Length();
for (i = 1; i <= n; i++)
{
B.Add(C, seqval->Value(i));
}
return C;
}
//=================================================================================================
static void FillList(const occ::handle<NCollection_HSequence<TopoDS_Shape>>& list,
const TopoDS_Shape& comp,
const bool expcomp)
{
for (TopoDS_Iterator it(comp); it.More(); it.Next())
{
const TopoDS_Shape& sub = it.Value();
if (sub.ShapeType() != TopAbs_COMPOUND)
{
list->Append(sub);
}
else if (!expcomp)
{
list->Append(sub);
}
else
{
FillList(list, sub, expcomp);
}
}
}
occ::handle<NCollection_HSequence<TopoDS_Shape>> ShapeExtend_Explorer::SeqFromCompound(
const TopoDS_Shape& comp,
const bool expcomp) const
{
occ::handle<NCollection_HSequence<TopoDS_Shape>> list = new NCollection_HSequence<TopoDS_Shape>();
if (comp.IsNull())
{
return list;
}
if (comp.ShapeType() != TopAbs_COMPOUND)
{
list->Append(comp);
return list;
}
FillList(list, comp, expcomp);
return list;
}
//=================================================================================================
void ShapeExtend_Explorer::ListFromSeq(
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& seqval,
NCollection_List<TopoDS_Shape>& lisval,
const bool clear) const
{
if (clear)
{
lisval.Clear();
}
if (seqval.IsNull())
{
return;
}
int i, nb = seqval->Length();
for (i = 1; i <= nb; i++)
{
lisval.Append(seqval->Value(i));
}
}
//=================================================================================================
occ::handle<NCollection_HSequence<TopoDS_Shape>> ShapeExtend_Explorer::SeqFromList(
const NCollection_List<TopoDS_Shape>& lisval) const
{
occ::handle<NCollection_HSequence<TopoDS_Shape>> seqval =
new NCollection_HSequence<TopoDS_Shape>();
NCollection_List<TopoDS_Shape>::Iterator it;
for (it.Initialize(lisval); it.More(); it.Next())
{
seqval->Append(it.Value());
}
return seqval;
}
//=================================================================================================
TopAbs_ShapeEnum ShapeExtend_Explorer::ShapeType(const TopoDS_Shape& shape,
const bool compound) const
{
if (shape.IsNull())
{
return TopAbs_SHAPE;
}
TopAbs_ShapeEnum res = shape.ShapeType();
if (!compound || res != TopAbs_COMPOUND)
{
return res;
}
res = TopAbs_SHAPE;
for (TopoDS_Iterator iter(shape); iter.More(); iter.Next())
{
const TopoDS_Shape& sh = iter.Value();
if (sh.IsNull())
{
continue;
}
TopAbs_ShapeEnum typ = sh.ShapeType();
if (typ == TopAbs_COMPOUND)
{
typ = ShapeType(sh, compound);
}
if (res == TopAbs_SHAPE)
{
res = typ;
// Egalite : OK; Pseudo-Egalite : EDGE/WIRE ou FACE/SHELL
}
else if (res == TopAbs_EDGE && typ == TopAbs_WIRE)
{
res = typ;
}
else if (res == TopAbs_WIRE && typ == TopAbs_EDGE)
{
continue;
}
else if (res == TopAbs_FACE && typ == TopAbs_SHELL)
{
res = typ;
}
else if (res == TopAbs_SHELL && typ == TopAbs_FACE)
{
continue;
}
else if (res != typ)
{
return TopAbs_COMPOUND;
}
}
return res;
}
//=================================================================================================
TopoDS_Shape ShapeExtend_Explorer::SortedCompound(const TopoDS_Shape& shape,
const TopAbs_ShapeEnum type,
const bool explore,
const bool compound) const
{
if (shape.IsNull())
{
return shape;
}
TopAbs_ShapeEnum typ = shape.ShapeType();
TopoDS_Shape sh, sh0;
int nb = 0;
// Compound : on le prend, soit tel quel, soit son contenu
if (typ == TopAbs_COMPOUND || typ == TopAbs_COMPSOLID)
{
TopoDS_Compound C;
BRep_Builder B;
B.MakeCompound(C);
for (TopoDS_Iterator it(shape); it.More(); it.Next())
{
sh0 = SortedCompound(it.Value(), type, explore, compound);
if (sh0.IsNull())
{
continue;
}
sh = sh0;
typ = sh.ShapeType();
if (typ == TopAbs_COMPOUND && !compound)
{
for (TopoDS_Iterator it2(sh); it2.More(); it2.Next())
{
nb++;
sh = it2.Value();
B.Add(C, sh);
}
}
else
{
nb++;
B.Add(C, sh);
}
}
if (nb == 0)
{
C.Nullify();
}
else if (nb == 1)
{
return sh;
}
return C;
}
// Egalite : OK; Pseudo-Egalite : EDGE/WIRE ou FACE/SHELL
if (typ == type)
{
return shape;
}
if (typ == TopAbs_EDGE && type == TopAbs_WIRE)
{
BRep_Builder B;
TopoDS_Wire W;
B.MakeWire(W);
B.Add(W, shape);
return W;
}
if (typ == TopAbs_FACE && type == TopAbs_SHELL)
{
BRep_Builder B;
TopoDS_Shell S;
B.MakeShell(S);
B.Add(S, shape);
return S;
}
// Le reste : selon exploration
if (!explore)
{
TopoDS_Shape nulsh;
return nulsh;
}
// Ici, on doit explorer
// SOLID + mode COMPOUND : reconduire les SHELLs
if (typ == TopAbs_SOLID && compound)
{
TopoDS_Compound C;
BRep_Builder B;
B.MakeCompound(C);
for (TopoDS_Iterator it(shape); it.More(); it.Next())
{
sh0 = SortedCompound(it.Value(), type, explore, compound);
if (sh0.IsNull())
{
continue;
}
sh = sh0;
nb++;
B.Add(C, sh);
}
if (nb == 0)
{
C.Nullify();
}
else if (nb == 1)
{
return sh;
}
return C;
}
// Exploration classique
TopoDS_Compound CC;
BRep_Builder BB;
BB.MakeCompound(CC);
// int iena = false; //szv#4:S4163:12Mar99 unused
for (TopExp_Explorer aExp(shape, type); aExp.More(); aExp.Next())
{
nb++;
sh = aExp.Current();
BB.Add(CC, sh);
}
if (nb == 0)
{
CC.Nullify();
}
else if (nb == 1)
{
return sh;
}
return CC;
}
//=================================================================================================
void ShapeExtend_Explorer::DispatchList(
const occ::handle<NCollection_HSequence<TopoDS_Shape>>& list,
occ::handle<NCollection_HSequence<TopoDS_Shape>>& vertices,
occ::handle<NCollection_HSequence<TopoDS_Shape>>& edges,
occ::handle<NCollection_HSequence<TopoDS_Shape>>& wires,
occ::handle<NCollection_HSequence<TopoDS_Shape>>& faces,
occ::handle<NCollection_HSequence<TopoDS_Shape>>& shells,
occ::handle<NCollection_HSequence<TopoDS_Shape>>& solids,
occ::handle<NCollection_HSequence<TopoDS_Shape>>& compsols,
occ::handle<NCollection_HSequence<TopoDS_Shape>>& compounds) const
{
if (list.IsNull())
{
return;
}
if (vertices.IsNull())
{
vertices = new NCollection_HSequence<TopoDS_Shape>();
}
if (edges.IsNull())
{
edges = new NCollection_HSequence<TopoDS_Shape>();
}
if (wires.IsNull())
{
wires = new NCollection_HSequence<TopoDS_Shape>();
}
if (faces.IsNull())
{
faces = new NCollection_HSequence<TopoDS_Shape>();
}
if (shells.IsNull())
{
shells = new NCollection_HSequence<TopoDS_Shape>();
}
if (solids.IsNull())
{
solids = new NCollection_HSequence<TopoDS_Shape>();
}
if (compsols.IsNull())
{
compsols = new NCollection_HSequence<TopoDS_Shape>();
}
if (compounds.IsNull())
{
compounds = new NCollection_HSequence<TopoDS_Shape>();
}
int i, nb = list->Length();
for (i = 1; i <= nb; i++)
{
TopoDS_Shape sh = list->Value(i);
if (sh.IsNull())
{
continue;
}
switch (sh.ShapeType())
{
case TopAbs_VERTEX:
vertices->Append(sh);
break;
case TopAbs_EDGE:
edges->Append(sh);
break;
case TopAbs_WIRE:
wires->Append(sh);
break;
case TopAbs_FACE:
faces->Append(sh);
break;
case TopAbs_SHELL:
shells->Append(sh);
break;
case TopAbs_SOLID:
solids->Append(sh);
break;
case TopAbs_COMPSOLID:
compsols->Append(sh);
break;
case TopAbs_COMPOUND:
compounds->Append(sh);
break;
default:
break;
}
}
}