From c07b5ec31288ecd950088d7f58ecdf38576cd782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Fri, 20 Jun 2014 11:19:58 +0200 Subject: [PATCH 01/63] first commit for the ceration of a t_shape plugin --- src/Tools/salome_plugins.py | 43 ++++++ src/Tools/t_shape_builder.py | 267 +++++++++++++++++++++++++++++++++ src/Tools/t_shape_dialog.py | 92 ++++++++++++ src/Tools/t_shape_dialog.ui | 115 ++++++++++++++ src/Tools/t_shape_dialog_ui.py | 90 +++++++++++ 5 files changed, 607 insertions(+) create mode 100644 src/Tools/salome_plugins.py create mode 100644 src/Tools/t_shape_builder.py create mode 100644 src/Tools/t_shape_dialog.py create mode 100644 src/Tools/t_shape_dialog.ui create mode 100644 src/Tools/t_shape_dialog_ui.py diff --git a/src/Tools/salome_plugins.py b/src/Tools/salome_plugins.py new file mode 100644 index 000000000..d18c49473 --- /dev/null +++ b/src/Tools/salome_plugins.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2010-2014 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Renaud Nédélec (OpenCascade S.A.S) + +import salome_pluginsmanager + +def t_shape_fluid(context): + activeStudy = context.study + import t_shape_dialog + dialog = t_shape_dialog.TShapeDialog() + + # Get the parameter values from a gui dialog box. If the dialog is + # closed using the Ok button, then the data are requested from the + # gui and used to create the shape of the tube. + dialog.exec_() + dialog.getData() + #if dialog.wasOk(): + #radius, length, width = dialog.getData() + #shape = tubebuilder.createGeometry(activeStudy, radius, length, width) + #entry = xalome.addToStudy(activeStudy, shape, "Tube" ) + #xalome.displayShape(entry) + + +salome_pluginsmanager.AddFunction('T shape fluid', + 'Creates the fluid part of a pipe T-shape', + t_shape_fluid) \ No newline at end of file diff --git a/src/Tools/t_shape_builder.py b/src/Tools/t_shape_builder.py new file mode 100644 index 000000000..899724e6c --- /dev/null +++ b/src/Tools/t_shape_builder.py @@ -0,0 +1,267 @@ +# -*- coding: iso-8859-1 -*- + +import sys +import salome + +salome.salome_init() +theStudy = salome.myStudy + +import GEOM +from salome.geom import geomBuilder +import math +import SALOMEDS + +geompy = geomBuilder.New(theStudy) + +O = geompy.MakeVertex(0, 0, 0) +OX = geompy.MakeVectorDXDYDZ(1, 0, 0) +OY = geompy.MakeVectorDXDYDZ(0, 1, 0) +OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) + +geompy.addToStudy( O, 'O' ) +geompy.addToStudy( OX, 'OX' ) +geompy.addToStudy( OY, 'OY' ) +geompy.addToStudy( OZ, 'OZ' ) + +r1 = 100.0 +r2 = 50.0 +h1 = 200.0 +h2 = 200.0 + +a1 = 45.0 +seuilmax = 0.1 +ratio = float(r2)/float(r1) +if ratio > (1.0 -seuilmax): + a1 = 45.0*(1.0 -ratio)/seuilmax + +def demidisk(r1, a1, roty=0): + v=range(8) + l=range(8) + v0 = geompy.MakeVertex(0, 0, 0) + v[0] = geompy.MakeVertex(0, r1/2.0, 0) + v[1] = geompy.MakeVertex(0, r1, 0) + l[1] = geompy.MakeLineTwoPnt(v[0], v[1]) + l[2] = geompy.MakeRotation(l[1], OX, a1*math.pi/180.0) + v[4] = geompy.MakeRotation(v[0], OX, a1*math.pi/180.0) + v[6] = geompy.MakeRotation(v[1], OX, a1*math.pi/180.0) + + v[2] = geompy.MakeVertex(0, -r1/2.0, 0) + v[3] = geompy.MakeVertex(0, -r1, 0) + l[3] = geompy.MakeLineTwoPnt(v[2], v[3]) + l[4] = geompy.MakeRotation(l[3], OX, -a1*math.pi/180.0) + v[5] = geompy.MakeRotation(v[2], OX, -a1*math.pi/180.0) + v[7] = geompy.MakeRotation(v[3], OX, -a1*math.pi/180.0) + + l[5] = geompy.MakeLineTwoPnt(v[4], v[5]) + l[6] = geompy.MakeLineTwoPnt(v[0], v[4]) + l[7] = geompy.MakeLineTwoPnt(v[2], v[5]) + + v7 = geompy.MakeVertex(0, 0, r1) + arc1 = geompy.MakeArc(v[1], v7, v[3]) + l[0] = geompy.MakeLineTwoPnt(v[1], v[3]) + face1 = geompy.MakeFaceWires([arc1, l[0]], 1) + part1 = geompy.MakePartition([face1], [l[2], l[4], l[5], l[6], l[7]], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) + + if roty != 0: + vrot = [ geompy.MakeRotation(vert, OY, roty*math.pi/180.0) for vert in v ] + lrot = [ geompy.MakeRotation(lin, OY, roty*math.pi/180.0) for lin in l ] + arc = geompy.MakeRotation(arc1, OY, roty*math.pi/180.0) + part = geompy.MakeRotation(part1, OY, roty*math.pi/180.0) + return vrot, lrot, arc, part + else: + return v, l, arc1, part1 + +def pointsProjetes(vref, face): + vface = geompy.ExtractShapes(face, geompy.ShapeType["VERTEX"], True) + vord = range(len(vref)) + plan = geompy.MakePlaneThreePnt(vref[0], vref[1], vref[-1], 10000) + vproj = [ geompy.MakeProjection(vert, plan) for vert in vface ] + for i,v in enumerate(vproj): + dist = [ (geompy.MinDistance(v, vr), j) for j,vr in enumerate(vref) ] + dist.sort() + #print dist + if dist[0][0] < 1.e-3: + vord[dist[0][1]] = vface[i] + return vord + +def arcsProjetes(vf, face): + lface = geompy.ExtractShapes(face, geompy.ShapeType["EDGE"], True) + lord = range(3) + ends = [vf[1], vf[6], vf[7], vf[3]] + for i in range(3): + for lf in lface: + pts = geompy.ExtractShapes(lf, geompy.ShapeType["VERTEX"], True) + if (((geompy.MinDistance(pts[0], ends[i]) < 0.001) and (geompy.MinDistance(pts[1], ends[i+1]) < 0.001)) or + ((geompy.MinDistance(pts[1], ends[i]) < 0.001) and (geompy.MinDistance(pts[0], ends[i+1]) < 0.001))): + lord[i] = lf + print "arc_%d OK"%i + break + pass + return lord + +# --- sections droites des deux demi cylindres avec le partionnement + +v1, l1, arc1, part1 = demidisk(r1, a1) +v2, l2, arc2, part2 = demidisk(r2, a1, 90.0) + +geompy.addToStudy(part1, 'part1') +geompy.addToStudy(part2, 'part2') + +# --- extrusion des sections --> demi cylindres de travail, pour en extraire les sections utilisées au niveau du Té +# et enveloppe cylindrique du cylindre principal + +demicyl1 = geompy.MakePrismVecH(part1, OX, h1) +demicyl2 = geompy.MakePrismVecH(part2, OZ, h2) +arcextru = geompy.MakePrismVecH(arc1, OX, h1) + +geompy.addToStudy(demicyl1, 'demicyl1') +geompy.addToStudy(demicyl2, 'demicyl2') +geompy.addToStudy(arcextru, 'arcextru') + +# --- plan de coupe à 45° sur le cylindre principal, +# section à 45° du cylndre principal, +# section du cylindre secondaire par l'enveloppe cylindique du cylindre principal + +plan1 = geompy.MakePlane(O, OX, 4*r1) +planr = geompy.MakeRotation(plan1, OY, 45*math.pi/180.0) +geompy.addToStudy(planr, 'planr') + +sect45 = geompy.MakeCommonList([demicyl1, planr], True) +geompy.addToStudy(sect45, 'sect45') + +sect90 = geompy.MakeCommonList([demicyl2, arcextru], True) +geompy.addToStudy(sect90, 'sect90') + +# --- liste ordonnée des points projetés sur les deux sections + +vord45 = pointsProjetes(v1, sect45) +vord90 = pointsProjetes(v2, sect90) +for i,v in enumerate(vord45): + geompy.addToStudyInFather(sect45, v, 'v%d'%i) +for i,v in enumerate(vord90): + geompy.addToStudyInFather(sect90, v, 'v%d'%i) + +# --- identification des projections des trois arcs de cercle, sur les deux sections. + +lord45 = arcsProjetes(vord45, sect45) +lord90 = arcsProjetes(vord90, sect90) +for i,l in enumerate(lord45): + geompy.addToStudyInFather(sect45, l, 'l%d'%i) +for i,l in enumerate(lord90): + geompy.addToStudyInFather(sect90, l, 'l%d'%i) + +# --- abaissement des quatre points centraux de la section du cylindre secondaire + +dz = -r2/2.0 +for i in (0, 2, 4, 5): + vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz, True) + geompy.addToStudyInFather(sect90, vord90[i], 'vm%d'%i) + +# --- création des deux arêtes curvilignes sur l'enveloppe cylindrique du cylindre principal, à la jonction + +curv = [None for i in range(4)] # liaisons entre les points 1, 3, 6 et 7 des 2 sections + +curv[0] = geompy.MakeArcCenter(O, vord90[1] , vord45[1], False) +curv[1] = geompy.MakeArcCenter(O, vord90[3] , vord45[3], False) + +lipts = ((6, 6, 4), (7, 7, 5)) +for i, ipts in enumerate(lipts): + print i, ipts + p0 = vord90[ipts[0]] + p1 = vord45[ipts[1]] + p2 = vord45[ipts[2]] + plan = geompy.MakePlaneThreePnt(p0, p1, p2, 10000) + #geompy.addToStudy(plan, "plan%d"%i) + section = geompy.MakeSection(plan, arcextru, True) + secpart = geompy.MakePartition([section], [sect45, sect90], [], [], geompy.ShapeType["EDGE"], 0, [], 0, True) + #geompy.addToStudy(secpart, "secpart%d"%i) + lsec = geompy.ExtractShapes(secpart, geompy.ShapeType["EDGE"], True) + #print "len(lsec)", len(lsec) + for l in lsec: + pts = geompy.ExtractShapes(l, geompy.ShapeType["VERTEX"], True) + if (((geompy.MinDistance(pts[0], p0) < 0.001) and (geompy.MinDistance(pts[1], p1) < 0.001)) or + ((geompy.MinDistance(pts[1], p0) < 0.001) and (geompy.MinDistance(pts[0], p1) < 0.001))): + curv[i+2] =l + #print "curv_%d OK"%i + break +for i,l in enumerate(curv): + geompy.addToStudyInFather(arcextru, l, "curv%d"%i) + +# --- creation des arêtes droites manquantes, des faces et volumes pour les quatre volumes de la jonction + +edges = [None for i in range(8)] +edges[0] = geompy.MakeLineTwoPnt(vord45[0], vord90[0]) +edges[1] = curv[0] +edges[2] = geompy.MakeLineTwoPnt(vord45[2], vord90[2]) +edges[3] = curv[1] +edges[4] = geompy.MakeLineTwoPnt(vord45[4], vord90[4]) +edges[5] = geompy.MakeLineTwoPnt(vord45[5], vord90[5]) +edges[6] = curv[2] +edges[7] = curv[3] +for i,l in enumerate(edges): + geompy.addToStudy( l, "edge%d"%i) + +ed45 = [None for i in range(8)] +ed45[0] = geompy.MakeLineTwoPnt(vord45[0], vord45[2]) +ed45[1] = geompy.MakeLineTwoPnt(vord45[0], vord45[1]) +ed45[2] = geompy.MakeLineTwoPnt(vord45[4], vord45[6]) +ed45[3] = geompy.MakeLineTwoPnt(vord45[2], vord45[3]) +ed45[4] = geompy.MakeLineTwoPnt(vord45[5], vord45[7]) +ed45[5] = geompy.MakeLineTwoPnt(vord45[4], vord45[5]) +ed45[6] = geompy.MakeLineTwoPnt(vord45[0], vord45[4]) +ed45[7] = geompy.MakeLineTwoPnt(vord45[2], vord45[5]) +for i,l in enumerate(ed45): + geompy.addToStudyInFather(sect45, l, "ed45_%d"%i) + +ed90 = [None for i in range(8)] +ed90[0] = geompy.MakeLineTwoPnt(vord90[0], vord90[2]) +ed90[1] = geompy.MakeLineTwoPnt(vord90[0], vord90[1]) +ed90[2] = geompy.MakeLineTwoPnt(vord90[4], vord90[6]) +ed90[3] = geompy.MakeLineTwoPnt(vord90[2], vord90[3]) +ed90[4] = geompy.MakeLineTwoPnt(vord90[5], vord90[7]) +ed90[5] = geompy.MakeLineTwoPnt(vord90[4], vord90[5]) +ed90[6] = geompy.MakeLineTwoPnt(vord90[0], vord90[4]) +ed90[7] = geompy.MakeLineTwoPnt(vord90[2], vord90[5]) +for i,l in enumerate(ed90): + geompy.addToStudyInFather(sect90, l, "ed90_%d"%i) + +faci = [] +faci.append(geompy.MakeFaceWires([ed45[6], edges[0], ed90[6], edges[4]], 0)) +faci.append(geompy.MakeFaceWires([ed45[7], edges[2], ed90[7], edges[5]], 0)) +faci.append(geompy.MakeFaceWires([ed45[2], edges[4], ed90[2], edges[6]], 0)) +faci.append(geompy.MakeFaceWires([ed45[5], edges[4], ed90[5], edges[5]], 0)) +faci.append(geompy.MakeFaceWires([ed45[4], edges[5], ed90[4], edges[7]], 0)) +faci.append(geompy.MakeFaceWires([ed90[0], ed90[6], ed90[5], ed90[7]], 0)) +faci.append(geompy.MakeFaceWires([ed90[1], ed90[6], ed90[2], lord90[0]], 0)) +faci.append(geompy.MakeFaceWires([ed90[2], ed90[5], ed90[4], lord90[1]], 0)) +faci.append(geompy.MakeFaceWires([ed90[3], ed90[7], ed90[4], lord90[2]], 0)) +for i,f in enumerate(faci): + geompy.addToStudy(f, "faci_%d"%i) + +# --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres + +extru1 = geompy.MakePrismVecH(sect45, OX, h1+10) +geompy.addToStudy(extru1, "extru1") + +base2 = geompy.MakePartition(faci[5:], [], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) +extru2 = geompy.MakePrismVecH(base2, OZ, h2) +geompy.addToStudy(extru2, "extru2") + +# --- partition et coupe + +demiDisque = geompy.MakeFaceWires([arc1, l1[0]], 1) +demiCylindre = geompy.MakePrismVecH(demiDisque, OX, h1) +#geompy.addToStudy(demiCylindre, "demiCylindre") +box = geompy.MakeBox(0, -2*(r1+h1), -2*(r1+h1), 2*(r1+h1), 2*(r1+h1), 2*(r1+h1)) +rot = geompy.MakeRotation(box, OY, 45*math.pi/180.0) +#geompy.addToStudy(rot, "rot") +garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True) +geompy.addToStudy(garder, "garder") +raccord = geompy.MakePartition([garder], faci, [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) +assemblage = geompy.MakePartition([raccord, extru1, extru2], [], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) +geompy.addToStudy(assemblage, "assemblage") + +box = geompy.MakeBox(-1, -(r1+r2), -1, h1, r1+r2, h2) +geompy.addToStudy(box, "box") +final = geompy.MakeCommonList([box, assemblage], True) +geompy.addToStudy(final, "final") diff --git a/src/Tools/t_shape_dialog.py b/src/Tools/t_shape_dialog.py new file mode 100644 index 000000000..563aca90c --- /dev/null +++ b/src/Tools/t_shape_dialog.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2010-2014 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Renaud Nédélec (OpenCascade S.A.S) + +import sys +from PyQt4 import QtGui +from PyQt4 import QtCore + +from t_shape_dialog_ui import Ui_Dialog + + +class TShapeDialog(QtGui.QDialog): + def __init__(self): + QtGui.QDialog.__init__(self, None, QtCore.Qt.Tool) + # Set up the user interface from Designer. + self.ui = Ui_Dialog() + self.ui.setupUi(self) + self.show() + + def accept(self): + print "DATA ACCEPTED" + self._wasOk = True + QtGui.QDialog.accept(self) + + def getData(self): + print "DATA : %f"%(self.ui.doubleSpinBox.value()) + + #def setupUi(self): + #TShapeDialog_UI.setupUi(self) + #self.handleAcceptWith(self.accept) + #self.handleRejectWith(self.reject) + + #def handleAcceptWith(self,callbackFunction): + #"""This defines the function to be connected to the signal 'accepted()' (click on Ok)""" + #QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), callbackFunction) + + #def handleRejectWith(self,callbackFunction): + #"""This defines the function to be connected to the signal 'rejected()' (click on Cancel)""" + #QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), callbackFunction) + + #def accept(self): + #'''Callback function when dialog is accepted (click Ok)''' + #self._wasOk = True + ## We should test here the validity of values + #QtGui.QDialog.accept(self) + + #def reject(self): + #'''Callback function when dialog is rejected (click Cancel)''' + #self._wasOk = False + #QtGui.QDialog.reject(self) + + #def wasOk(self): + #return self._wasOk + + #def setData(self): + #pass + + #def getData(self): + #pass + +# ================ +# Tests +# ================ + +def main( args ): + import sys + app = QtGui.QApplication(sys.argv) + Dialog = TShapeDialog() + ui = Ui_Dialog() + ui.setupUi(Dialog) + Dialog.show() + sys.exit(app.exec_()) + +if __name__=="__main__": + main(sys.argv) diff --git a/src/Tools/t_shape_dialog.ui b/src/Tools/t_shape_dialog.ui new file mode 100644 index 000000000..7a9a52471 --- /dev/null +++ b/src/Tools/t_shape_dialog.ui @@ -0,0 +1,115 @@ + + + Dialog + + + + 0 + 0 + 321 + 242 + + + + Dialog + + + + + + + + + + + Big pipe radius + + + + + + + + + + + + + + + + Big pipe height + + + + + + + Small pipe radius + + + + + + + Small pipe height + + + + + + + + + Build solid part + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/Tools/t_shape_dialog_ui.py b/src/Tools/t_shape_dialog_ui.py new file mode 100644 index 000000000..c4353e11f --- /dev/null +++ b/src/Tools/t_shape_dialog_ui.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 't_shape_dialog.ui' +# +# Created: Thu Jun 19 11:13:43 2014 +# by: PyQt4 UI code generator 4.9.6 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName(_fromUtf8("Dialog")) + Dialog.resize(331, 242) + self.verticalLayout = QtGui.QVBoxLayout(Dialog) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.gridLayout = QtGui.QGridLayout() + self.gridLayout.setObjectName(_fromUtf8("gridLayout")) + self.doubleSpinBox_2 = QtGui.QDoubleSpinBox(Dialog) + self.doubleSpinBox_2.setObjectName(_fromUtf8("doubleSpinBox_2")) + self.gridLayout.addWidget(self.doubleSpinBox_2, 2, 1, 1, 1) + self.label = QtGui.QLabel(Dialog) + self.label.setObjectName(_fromUtf8("label")) + self.gridLayout.addWidget(self.label, 0, 0, 1, 1) + self.doubleSpinBox_3 = QtGui.QDoubleSpinBox(Dialog) + self.doubleSpinBox_3.setObjectName(_fromUtf8("doubleSpinBox_3")) + self.gridLayout.addWidget(self.doubleSpinBox_3, 3, 1, 1, 1) + self.doubleSpinBox_4 = QtGui.QDoubleSpinBox(Dialog) + self.doubleSpinBox_4.setObjectName(_fromUtf8("doubleSpinBox_4")) + self.gridLayout.addWidget(self.doubleSpinBox_4, 4, 1, 1, 1) + self.doubleSpinBox = QtGui.QDoubleSpinBox(Dialog) + self.doubleSpinBox.setObjectName(_fromUtf8("doubleSpinBox")) + self.gridLayout.addWidget(self.doubleSpinBox, 0, 1, 1, 1) + self.label_3 = QtGui.QLabel(Dialog) + self.label_3.setObjectName(_fromUtf8("label_3")) + self.gridLayout.addWidget(self.label_3, 3, 0, 1, 1) + self.label_2 = QtGui.QLabel(Dialog) + self.label_2.setObjectName(_fromUtf8("label_2")) + self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1) + self.label_4 = QtGui.QLabel(Dialog) + self.label_4.setObjectName(_fromUtf8("label_4")) + self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1) + self.verticalLayout.addLayout(self.gridLayout) + self.checkBox = QtGui.QCheckBox(Dialog) + self.checkBox.setObjectName(_fromUtf8("checkBox")) + self.verticalLayout.addWidget(self.checkBox) + self.buttonBox = QtGui.QDialogButtonBox(Dialog) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) + self.buttonBox.setObjectName(_fromUtf8("buttonBox")) + self.verticalLayout.addWidget(self.buttonBox) + + self.retranslateUi(Dialog) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject) + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + Dialog.setWindowTitle(_translate("Dialog", "Dialog", None)) + self.label.setText(_translate("Dialog", "Big pipe radius", None)) + self.label_3.setText(_translate("Dialog", "Big pipe height", None)) + self.label_2.setText(_translate("Dialog", "Small pipe radius", None)) + self.label_4.setText(_translate("Dialog", "Small pipe height", None)) + self.checkBox.setText(_translate("Dialog", "Build solid part", None)) + + +if __name__ == "__main__": + import sys + app = QtGui.QApplication(sys.argv) + Dialog = QtGui.QDialog() + ui = Ui_Dialog() + ui.setupUi(Dialog) + Dialog.show() + sys.exit(app.exec_()) + From 4d7ec7e96b0345afc50b121cacbae59d9fa970bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Fri, 20 Jun 2014 11:57:06 +0200 Subject: [PATCH 02/63] first working version of the plugin --- src/Tools/salome_plugins.py | 10 +- src/Tools/t_shape_builder.py | 387 ++++++++++++++++++----------------- src/Tools/t_shape_dialog.py | 7 +- 3 files changed, 215 insertions(+), 189 deletions(-) diff --git a/src/Tools/salome_plugins.py b/src/Tools/salome_plugins.py index d18c49473..ba7e9753e 100644 --- a/src/Tools/salome_plugins.py +++ b/src/Tools/salome_plugins.py @@ -22,15 +22,21 @@ import salome_pluginsmanager def t_shape_fluid(context): - activeStudy = context.study + import t_shape_builder import t_shape_dialog + import xalome + activeStudy = context.study + dialog = t_shape_dialog.TShapeDialog() # Get the parameter values from a gui dialog box. If the dialog is # closed using the Ok button, then the data are requested from the # gui and used to create the shape of the tube. dialog.exec_() - dialog.getData() + r1, r2, h1, h2 = dialog.getData() + shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2) + entry = xalome.addToStudy(activeStudy, shape, "T_shape_fluid" ) + xalome.displayShape(entry) #if dialog.wasOk(): #radius, length, width = dialog.getData() #shape = tubebuilder.createGeometry(activeStudy, radius, length, width) diff --git a/src/Tools/t_shape_builder.py b/src/Tools/t_shape_builder.py index 899724e6c..d905f0545 100644 --- a/src/Tools/t_shape_builder.py +++ b/src/Tools/t_shape_builder.py @@ -3,38 +3,35 @@ import sys import salome -salome.salome_init() -theStudy = salome.myStudy - import GEOM from salome.geom import geomBuilder import math import SALOMEDS -geompy = geomBuilder.New(theStudy) -O = geompy.MakeVertex(0, 0, 0) -OX = geompy.MakeVectorDXDYDZ(1, 0, 0) -OY = geompy.MakeVectorDXDYDZ(0, 1, 0) -OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) +#O = geompy.MakeVertex(0, 0, 0) +#OX = geompy.MakeVectorDXDYDZ(1, 0, 0) +#OY = geompy.MakeVectorDXDYDZ(0, 1, 0) +#OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) -geompy.addToStudy( O, 'O' ) -geompy.addToStudy( OX, 'OX' ) -geompy.addToStudy( OY, 'OY' ) -geompy.addToStudy( OZ, 'OZ' ) +#geompy.addToStudy( O, 'O' ) +#geompy.addToStudy( OX, 'OX' ) +#geompy.addToStudy( OY, 'OY' ) +#geompy.addToStudy( OZ, 'OZ' ) -r1 = 100.0 -r2 = 50.0 -h1 = 200.0 -h2 = 200.0 +#r1 = 100.0 +#r2 = 50.0 +#h1 = 200.0 +#h2 = 200.0 -a1 = 45.0 -seuilmax = 0.1 -ratio = float(r2)/float(r1) -if ratio > (1.0 -seuilmax): - a1 = 45.0*(1.0 -ratio)/seuilmax - -def demidisk(r1, a1, roty=0): +def demidisk(study, r1, a1, roty=0): + geompy = geomBuilder.New(study) + + O = geompy.MakeVertex(0, 0, 0) + OX = geompy.MakeVectorDXDYDZ(1, 0, 0) + OY = geompy.MakeVectorDXDYDZ(0, 1, 0) + OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) + v=range(8) l=range(8) v0 = geompy.MakeVertex(0, 0, 0) @@ -71,7 +68,8 @@ def demidisk(r1, a1, roty=0): else: return v, l, arc1, part1 -def pointsProjetes(vref, face): +def pointsProjetes(study, vref, face): + geompy = geomBuilder.New(study) vface = geompy.ExtractShapes(face, geompy.ShapeType["VERTEX"], True) vord = range(len(vref)) plan = geompy.MakePlaneThreePnt(vref[0], vref[1], vref[-1], 10000) @@ -84,7 +82,8 @@ def pointsProjetes(vref, face): vord[dist[0][1]] = vface[i] return vord -def arcsProjetes(vf, face): +def arcsProjetes(study, vf, face): + geompy = geomBuilder.New(study) lface = geompy.ExtractShapes(face, geompy.ShapeType["EDGE"], True) lord = range(3) ends = [vf[1], vf[6], vf[7], vf[3]] @@ -98,170 +97,186 @@ def arcsProjetes(vf, face): break pass return lord + +def build_shape(study, r1, r2, h1, h2): + geompy = geomBuilder.New(study) -# --- sections droites des deux demi cylindres avec le partionnement - -v1, l1, arc1, part1 = demidisk(r1, a1) -v2, l2, arc2, part2 = demidisk(r2, a1, 90.0) - -geompy.addToStudy(part1, 'part1') -geompy.addToStudy(part2, 'part2') - -# --- extrusion des sections --> demi cylindres de travail, pour en extraire les sections utilisées au niveau du Té -# et enveloppe cylindrique du cylindre principal - -demicyl1 = geompy.MakePrismVecH(part1, OX, h1) -demicyl2 = geompy.MakePrismVecH(part2, OZ, h2) -arcextru = geompy.MakePrismVecH(arc1, OX, h1) - -geompy.addToStudy(demicyl1, 'demicyl1') -geompy.addToStudy(demicyl2, 'demicyl2') -geompy.addToStudy(arcextru, 'arcextru') - -# --- plan de coupe à 45° sur le cylindre principal, -# section à 45° du cylndre principal, -# section du cylindre secondaire par l'enveloppe cylindique du cylindre principal - -plan1 = geompy.MakePlane(O, OX, 4*r1) -planr = geompy.MakeRotation(plan1, OY, 45*math.pi/180.0) -geompy.addToStudy(planr, 'planr') - -sect45 = geompy.MakeCommonList([demicyl1, planr], True) -geompy.addToStudy(sect45, 'sect45') - -sect90 = geompy.MakeCommonList([demicyl2, arcextru], True) -geompy.addToStudy(sect90, 'sect90') - -# --- liste ordonnée des points projetés sur les deux sections - -vord45 = pointsProjetes(v1, sect45) -vord90 = pointsProjetes(v2, sect90) -for i,v in enumerate(vord45): - geompy.addToStudyInFather(sect45, v, 'v%d'%i) -for i,v in enumerate(vord90): - geompy.addToStudyInFather(sect90, v, 'v%d'%i) - -# --- identification des projections des trois arcs de cercle, sur les deux sections. - -lord45 = arcsProjetes(vord45, sect45) -lord90 = arcsProjetes(vord90, sect90) -for i,l in enumerate(lord45): - geompy.addToStudyInFather(sect45, l, 'l%d'%i) -for i,l in enumerate(lord90): - geompy.addToStudyInFather(sect90, l, 'l%d'%i) - -# --- abaissement des quatre points centraux de la section du cylindre secondaire - -dz = -r2/2.0 -for i in (0, 2, 4, 5): - vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz, True) - geompy.addToStudyInFather(sect90, vord90[i], 'vm%d'%i) + O = geompy.MakeVertex(0, 0, 0) + OX = geompy.MakeVectorDXDYDZ(1, 0, 0) + OY = geompy.MakeVectorDXDYDZ(0, 1, 0) + OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) -# --- création des deux arêtes curvilignes sur l'enveloppe cylindrique du cylindre principal, à la jonction + a1 = 45.0 + seuilmax = 0.1 + ratio = float(r2)/float(r1) + if ratio > (1.0 -seuilmax): + a1 = 45.0*(1.0 -ratio)/seuilmax + + + # --- sections droites des deux demi cylindres avec le partionnement -curv = [None for i in range(4)] # liaisons entre les points 1, 3, 6 et 7 des 2 sections + v1, l1, arc1, part1 = demidisk(study, r1, a1) + v2, l2, arc2, part2 = demidisk(study, r2, a1, 90.0) -curv[0] = geompy.MakeArcCenter(O, vord90[1] , vord45[1], False) -curv[1] = geompy.MakeArcCenter(O, vord90[3] , vord45[3], False) + geompy.addToStudy(part1, 'part1') + geompy.addToStudy(part2, 'part2') -lipts = ((6, 6, 4), (7, 7, 5)) -for i, ipts in enumerate(lipts): - print i, ipts - p0 = vord90[ipts[0]] - p1 = vord45[ipts[1]] - p2 = vord45[ipts[2]] - plan = geompy.MakePlaneThreePnt(p0, p1, p2, 10000) - #geompy.addToStudy(plan, "plan%d"%i) - section = geompy.MakeSection(plan, arcextru, True) - secpart = geompy.MakePartition([section], [sect45, sect90], [], [], geompy.ShapeType["EDGE"], 0, [], 0, True) - #geompy.addToStudy(secpart, "secpart%d"%i) - lsec = geompy.ExtractShapes(secpart, geompy.ShapeType["EDGE"], True) - #print "len(lsec)", len(lsec) - for l in lsec: - pts = geompy.ExtractShapes(l, geompy.ShapeType["VERTEX"], True) - if (((geompy.MinDistance(pts[0], p0) < 0.001) and (geompy.MinDistance(pts[1], p1) < 0.001)) or - ((geompy.MinDistance(pts[1], p0) < 0.001) and (geompy.MinDistance(pts[0], p1) < 0.001))): - curv[i+2] =l - #print "curv_%d OK"%i - break -for i,l in enumerate(curv): - geompy.addToStudyInFather(arcextru, l, "curv%d"%i) + # --- extrusion des sections --> demi cylindres de travail, pour en extraire les sections utilisées au niveau du Té + # et enveloppe cylindrique du cylindre principal + + demicyl1 = geompy.MakePrismVecH(part1, OX, h1) + demicyl2 = geompy.MakePrismVecH(part2, OZ, h2) + arcextru = geompy.MakePrismVecH(arc1, OX, h1) + + geompy.addToStudy(demicyl1, 'demicyl1') + geompy.addToStudy(demicyl2, 'demicyl2') + geompy.addToStudy(arcextru, 'arcextru') + + # --- plan de coupe à 45° sur le cylindre principal, + # section à 45° du cylndre principal, + # section du cylindre secondaire par l'enveloppe cylindique du cylindre principal + + plan1 = geompy.MakePlane(O, OX, 4*r1) + planr = geompy.MakeRotation(plan1, OY, 45*math.pi/180.0) + geompy.addToStudy(planr, 'planr') + + sect45 = geompy.MakeCommonList([demicyl1, planr], True) + geompy.addToStudy(sect45, 'sect45') + + sect90 = geompy.MakeCommonList([demicyl2, arcextru], True) + geompy.addToStudy(sect90, 'sect90') + + # --- liste ordonnée des points projetés sur les deux sections + + vord45 = pointsProjetes(study, v1, sect45) + vord90 = pointsProjetes(study, v2, sect90) + for i,v in enumerate(vord45): + geompy.addToStudyInFather(sect45, v, 'v%d'%i) + for i,v in enumerate(vord90): + geompy.addToStudyInFather(sect90, v, 'v%d'%i) + + # --- identification des projections des trois arcs de cercle, sur les deux sections. + + lord45 = arcsProjetes(study, vord45, sect45) + lord90 = arcsProjetes(study, vord90, sect90) + for i,l in enumerate(lord45): + geompy.addToStudyInFather(sect45, l, 'l%d'%i) + for i,l in enumerate(lord90): + geompy.addToStudyInFather(sect90, l, 'l%d'%i) + + # --- abaissement des quatre points centraux de la section du cylindre secondaire + + dz = -r2/2.0 + for i in (0, 2, 4, 5): + vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz, True) + geompy.addToStudyInFather(sect90, vord90[i], 'vm%d'%i) + + # --- création des deux arêtes curvilignes sur l'enveloppe cylindrique du cylindre principal, à la jonction + + curv = [None for i in range(4)] # liaisons entre les points 1, 3, 6 et 7 des 2 sections + + curv[0] = geompy.MakeArcCenter(O, vord90[1] , vord45[1], False) + curv[1] = geompy.MakeArcCenter(O, vord90[3] , vord45[3], False) + + lipts = ((6, 6, 4), (7, 7, 5)) + for i, ipts in enumerate(lipts): + print i, ipts + p0 = vord90[ipts[0]] + p1 = vord45[ipts[1]] + p2 = vord45[ipts[2]] + plan = geompy.MakePlaneThreePnt(p0, p1, p2, 10000) + #geompy.addToStudy(plan, "plan%d"%i) + section = geompy.MakeSection(plan, arcextru, True) + secpart = geompy.MakePartition([section], [sect45, sect90], [], [], geompy.ShapeType["EDGE"], 0, [], 0, True) + #geompy.addToStudy(secpart, "secpart%d"%i) + lsec = geompy.ExtractShapes(secpart, geompy.ShapeType["EDGE"], True) + #print "len(lsec)", len(lsec) + for l in lsec: + pts = geompy.ExtractShapes(l, geompy.ShapeType["VERTEX"], True) + if (((geompy.MinDistance(pts[0], p0) < 0.001) and (geompy.MinDistance(pts[1], p1) < 0.001)) or + ((geompy.MinDistance(pts[1], p0) < 0.001) and (geompy.MinDistance(pts[0], p1) < 0.001))): + curv[i+2] =l + #print "curv_%d OK"%i + break + for i,l in enumerate(curv): + geompy.addToStudyInFather(arcextru, l, "curv%d"%i) + + # --- creation des arêtes droites manquantes, des faces et volumes pour les quatre volumes de la jonction + + edges = [None for i in range(8)] + edges[0] = geompy.MakeLineTwoPnt(vord45[0], vord90[0]) + edges[1] = curv[0] + edges[2] = geompy.MakeLineTwoPnt(vord45[2], vord90[2]) + edges[3] = curv[1] + edges[4] = geompy.MakeLineTwoPnt(vord45[4], vord90[4]) + edges[5] = geompy.MakeLineTwoPnt(vord45[5], vord90[5]) + edges[6] = curv[2] + edges[7] = curv[3] + for i,l in enumerate(edges): + geompy.addToStudy( l, "edge%d"%i) + + ed45 = [None for i in range(8)] + ed45[0] = geompy.MakeLineTwoPnt(vord45[0], vord45[2]) + ed45[1] = geompy.MakeLineTwoPnt(vord45[0], vord45[1]) + ed45[2] = geompy.MakeLineTwoPnt(vord45[4], vord45[6]) + ed45[3] = geompy.MakeLineTwoPnt(vord45[2], vord45[3]) + ed45[4] = geompy.MakeLineTwoPnt(vord45[5], vord45[7]) + ed45[5] = geompy.MakeLineTwoPnt(vord45[4], vord45[5]) + ed45[6] = geompy.MakeLineTwoPnt(vord45[0], vord45[4]) + ed45[7] = geompy.MakeLineTwoPnt(vord45[2], vord45[5]) + for i,l in enumerate(ed45): + geompy.addToStudyInFather(sect45, l, "ed45_%d"%i) + + ed90 = [None for i in range(8)] + ed90[0] = geompy.MakeLineTwoPnt(vord90[0], vord90[2]) + ed90[1] = geompy.MakeLineTwoPnt(vord90[0], vord90[1]) + ed90[2] = geompy.MakeLineTwoPnt(vord90[4], vord90[6]) + ed90[3] = geompy.MakeLineTwoPnt(vord90[2], vord90[3]) + ed90[4] = geompy.MakeLineTwoPnt(vord90[5], vord90[7]) + ed90[5] = geompy.MakeLineTwoPnt(vord90[4], vord90[5]) + ed90[6] = geompy.MakeLineTwoPnt(vord90[0], vord90[4]) + ed90[7] = geompy.MakeLineTwoPnt(vord90[2], vord90[5]) + for i,l in enumerate(ed90): + geompy.addToStudyInFather(sect90, l, "ed90_%d"%i) + + faci = [] + faci.append(geompy.MakeFaceWires([ed45[6], edges[0], ed90[6], edges[4]], 0)) + faci.append(geompy.MakeFaceWires([ed45[7], edges[2], ed90[7], edges[5]], 0)) + faci.append(geompy.MakeFaceWires([ed45[2], edges[4], ed90[2], edges[6]], 0)) + faci.append(geompy.MakeFaceWires([ed45[5], edges[4], ed90[5], edges[5]], 0)) + faci.append(geompy.MakeFaceWires([ed45[4], edges[5], ed90[4], edges[7]], 0)) + faci.append(geompy.MakeFaceWires([ed90[0], ed90[6], ed90[5], ed90[7]], 0)) + faci.append(geompy.MakeFaceWires([ed90[1], ed90[6], ed90[2], lord90[0]], 0)) + faci.append(geompy.MakeFaceWires([ed90[2], ed90[5], ed90[4], lord90[1]], 0)) + faci.append(geompy.MakeFaceWires([ed90[3], ed90[7], ed90[4], lord90[2]], 0)) + for i,f in enumerate(faci): + geompy.addToStudy(f, "faci_%d"%i) + + # --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres + + extru1 = geompy.MakePrismVecH(sect45, OX, h1+10) + geompy.addToStudy(extru1, "extru1") + + base2 = geompy.MakePartition(faci[5:], [], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) + extru2 = geompy.MakePrismVecH(base2, OZ, h2) + geompy.addToStudy(extru2, "extru2") + + # --- partition et coupe + + demiDisque = geompy.MakeFaceWires([arc1, l1[0]], 1) + demiCylindre = geompy.MakePrismVecH(demiDisque, OX, h1) + #geompy.addToStudy(demiCylindre, "demiCylindre") + box = geompy.MakeBox(0, -2*(r1+h1), -2*(r1+h1), 2*(r1+h1), 2*(r1+h1), 2*(r1+h1)) + rot = geompy.MakeRotation(box, OY, 45*math.pi/180.0) + #geompy.addToStudy(rot, "rot") + garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True) + geompy.addToStudy(garder, "garder") + raccord = geompy.MakePartition([garder], faci, [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) + assemblage = geompy.MakePartition([raccord, extru1, extru2], [], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) + geompy.addToStudy(assemblage, "assemblage") + + box = geompy.MakeBox(-1, -(r1+r2), -1, h1, r1+r2, h2) + geompy.addToStudy(box, "box") + final = geompy.MakeCommonList([box, assemblage], True) -# --- creation des arêtes droites manquantes, des faces et volumes pour les quatre volumes de la jonction - -edges = [None for i in range(8)] -edges[0] = geompy.MakeLineTwoPnt(vord45[0], vord90[0]) -edges[1] = curv[0] -edges[2] = geompy.MakeLineTwoPnt(vord45[2], vord90[2]) -edges[3] = curv[1] -edges[4] = geompy.MakeLineTwoPnt(vord45[4], vord90[4]) -edges[5] = geompy.MakeLineTwoPnt(vord45[5], vord90[5]) -edges[6] = curv[2] -edges[7] = curv[3] -for i,l in enumerate(edges): - geompy.addToStudy( l, "edge%d"%i) - -ed45 = [None for i in range(8)] -ed45[0] = geompy.MakeLineTwoPnt(vord45[0], vord45[2]) -ed45[1] = geompy.MakeLineTwoPnt(vord45[0], vord45[1]) -ed45[2] = geompy.MakeLineTwoPnt(vord45[4], vord45[6]) -ed45[3] = geompy.MakeLineTwoPnt(vord45[2], vord45[3]) -ed45[4] = geompy.MakeLineTwoPnt(vord45[5], vord45[7]) -ed45[5] = geompy.MakeLineTwoPnt(vord45[4], vord45[5]) -ed45[6] = geompy.MakeLineTwoPnt(vord45[0], vord45[4]) -ed45[7] = geompy.MakeLineTwoPnt(vord45[2], vord45[5]) -for i,l in enumerate(ed45): - geompy.addToStudyInFather(sect45, l, "ed45_%d"%i) - -ed90 = [None for i in range(8)] -ed90[0] = geompy.MakeLineTwoPnt(vord90[0], vord90[2]) -ed90[1] = geompy.MakeLineTwoPnt(vord90[0], vord90[1]) -ed90[2] = geompy.MakeLineTwoPnt(vord90[4], vord90[6]) -ed90[3] = geompy.MakeLineTwoPnt(vord90[2], vord90[3]) -ed90[4] = geompy.MakeLineTwoPnt(vord90[5], vord90[7]) -ed90[5] = geompy.MakeLineTwoPnt(vord90[4], vord90[5]) -ed90[6] = geompy.MakeLineTwoPnt(vord90[0], vord90[4]) -ed90[7] = geompy.MakeLineTwoPnt(vord90[2], vord90[5]) -for i,l in enumerate(ed90): - geompy.addToStudyInFather(sect90, l, "ed90_%d"%i) - -faci = [] -faci.append(geompy.MakeFaceWires([ed45[6], edges[0], ed90[6], edges[4]], 0)) -faci.append(geompy.MakeFaceWires([ed45[7], edges[2], ed90[7], edges[5]], 0)) -faci.append(geompy.MakeFaceWires([ed45[2], edges[4], ed90[2], edges[6]], 0)) -faci.append(geompy.MakeFaceWires([ed45[5], edges[4], ed90[5], edges[5]], 0)) -faci.append(geompy.MakeFaceWires([ed45[4], edges[5], ed90[4], edges[7]], 0)) -faci.append(geompy.MakeFaceWires([ed90[0], ed90[6], ed90[5], ed90[7]], 0)) -faci.append(geompy.MakeFaceWires([ed90[1], ed90[6], ed90[2], lord90[0]], 0)) -faci.append(geompy.MakeFaceWires([ed90[2], ed90[5], ed90[4], lord90[1]], 0)) -faci.append(geompy.MakeFaceWires([ed90[3], ed90[7], ed90[4], lord90[2]], 0)) -for i,f in enumerate(faci): - geompy.addToStudy(f, "faci_%d"%i) - -# --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres - -extru1 = geompy.MakePrismVecH(sect45, OX, h1+10) -geompy.addToStudy(extru1, "extru1") - -base2 = geompy.MakePartition(faci[5:], [], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) -extru2 = geompy.MakePrismVecH(base2, OZ, h2) -geompy.addToStudy(extru2, "extru2") - -# --- partition et coupe - -demiDisque = geompy.MakeFaceWires([arc1, l1[0]], 1) -demiCylindre = geompy.MakePrismVecH(demiDisque, OX, h1) -#geompy.addToStudy(demiCylindre, "demiCylindre") -box = geompy.MakeBox(0, -2*(r1+h1), -2*(r1+h1), 2*(r1+h1), 2*(r1+h1), 2*(r1+h1)) -rot = geompy.MakeRotation(box, OY, 45*math.pi/180.0) -#geompy.addToStudy(rot, "rot") -garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True) -geompy.addToStudy(garder, "garder") -raccord = geompy.MakePartition([garder], faci, [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) -assemblage = geompy.MakePartition([raccord, extru1, extru2], [], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) -geompy.addToStudy(assemblage, "assemblage") - -box = geompy.MakeBox(-1, -(r1+r2), -1, h1, r1+r2, h2) -geompy.addToStudy(box, "box") -final = geompy.MakeCommonList([box, assemblage], True) -geompy.addToStudy(final, "final") + return final diff --git a/src/Tools/t_shape_dialog.py b/src/Tools/t_shape_dialog.py index 563aca90c..cfffe27af 100644 --- a/src/Tools/t_shape_dialog.py +++ b/src/Tools/t_shape_dialog.py @@ -40,7 +40,12 @@ class TShapeDialog(QtGui.QDialog): QtGui.QDialog.accept(self) def getData(self): - print "DATA : %f"%(self.ui.doubleSpinBox.value()) + r1 = self.ui.doubleSpinBox.value() + r2 = self.ui.doubleSpinBox_2.value() + h1 = self.ui.doubleSpinBox_3.value() + h2 = self.ui.doubleSpinBox_4.value() + + return r1, r2, h1, h2 #def setupUi(self): #TShapeDialog_UI.setupUi(self) From e53c3df090686392c3b5f43af6d012762c13ecfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Fri, 20 Jun 2014 13:32:55 +0200 Subject: [PATCH 03/63] small modifications for cancel action to work correctly --- src/Tools/salome_plugins.py | 11 +++++++---- src/Tools/t_shape_dialog.py | 12 ++++++------ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Tools/salome_plugins.py b/src/Tools/salome_plugins.py index ba7e9753e..d75b4a7b1 100644 --- a/src/Tools/salome_plugins.py +++ b/src/Tools/salome_plugins.py @@ -25,6 +25,7 @@ def t_shape_fluid(context): import t_shape_builder import t_shape_dialog import xalome + from PyQt4.QtGui import QMessageBox activeStudy = context.study dialog = t_shape_dialog.TShapeDialog() @@ -33,10 +34,12 @@ def t_shape_fluid(context): # closed using the Ok button, then the data are requested from the # gui and used to create the shape of the tube. dialog.exec_() - r1, r2, h1, h2 = dialog.getData() - shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2) - entry = xalome.addToStudy(activeStudy, shape, "T_shape_fluid" ) - xalome.displayShape(entry) + if dialog.wasOk(): + r1, r2, h1, h2 = dialog.getData() + QMessageBox.about(None, "Building in progress", "building shape, please be patient") + shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2) + entry = xalome.addToStudy(activeStudy, shape, "T_shape_fluid" ) + xalome.displayShape(entry) #if dialog.wasOk(): #radius, length, width = dialog.getData() #shape = tubebuilder.createGeometry(activeStudy, radius, length, width) diff --git a/src/Tools/t_shape_dialog.py b/src/Tools/t_shape_dialog.py index cfffe27af..6ac37c51f 100644 --- a/src/Tools/t_shape_dialog.py +++ b/src/Tools/t_shape_dialog.py @@ -33,6 +33,7 @@ class TShapeDialog(QtGui.QDialog): self.ui = Ui_Dialog() self.ui.setupUi(self) self.show() + self._wasOk = False def accept(self): print "DATA ACCEPTED" @@ -66,13 +67,12 @@ class TShapeDialog(QtGui.QDialog): ## We should test here the validity of values #QtGui.QDialog.accept(self) - #def reject(self): - #'''Callback function when dialog is rejected (click Cancel)''' - #self._wasOk = False - #QtGui.QDialog.reject(self) + def reject(self): + self._wasOk = False + QtGui.QDialog.reject(self) - #def wasOk(self): - #return self._wasOk + def wasOk(self): + return self._wasOk #def setData(self): #pass From 54a9a7984f8294f907d2b23e7d8e349a13f9319c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Mon, 23 Jun 2014 14:22:53 +0200 Subject: [PATCH 04/63] complete t-shape pipe --- src/Tools/t_shape_builder.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/Tools/t_shape_builder.py b/src/Tools/t_shape_builder.py index d905f0545..2f6bc6ba2 100644 --- a/src/Tools/t_shape_builder.py +++ b/src/Tools/t_shape_builder.py @@ -9,21 +9,6 @@ import math import SALOMEDS -#O = geompy.MakeVertex(0, 0, 0) -#OX = geompy.MakeVectorDXDYDZ(1, 0, 0) -#OY = geompy.MakeVectorDXDYDZ(0, 1, 0) -#OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) - -#geompy.addToStudy( O, 'O' ) -#geompy.addToStudy( OX, 'OX' ) -#geompy.addToStudy( OY, 'OY' ) -#geompy.addToStudy( OZ, 'OZ' ) - -#r1 = 100.0 -#r2 = 50.0 -#h1 = 200.0 -#h2 = 200.0 - def demidisk(study, r1, a1, roty=0): geompy = geomBuilder.New(study) @@ -279,4 +264,17 @@ def build_shape(study, r1, r2, h1, h2): geompy.addToStudy(box, "box") final = geompy.MakeCommonList([box, assemblage], True) + # --- Partie infiérieure + v3, l3, arc3, part3 = demidisk(study, r1, a1, 180.0) + geompy.addToStudy(part3,"part3") + extru3 = geompy.MakePrismVecH(part3, OX, h1) + geompy.addToStudy(extru3,"extru3") + + # --- Symétrie + + compound = geompy.MakeCompound([final, extru3]) + plane = geompy.MakePlane(O,OX,2000) + compound_mirrored = geompy.MakeMirrorByPlane(compound, plane) + final = geompy.MakeCompound([compound, compound_mirrored]) + return final From a71898b2c0e4f0c129b9c488f70105c7448dfe3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Mon, 23 Jun 2014 16:25:36 +0200 Subject: [PATCH 05/63] some cleaning --- src/Tools/salome_plugins.py | 2 +- src/Tools/t_shape_builder.py | 15 ++------------- src/Tools/t_shape_dialog.py | 25 ------------------------- 3 files changed, 3 insertions(+), 39 deletions(-) diff --git a/src/Tools/salome_plugins.py b/src/Tools/salome_plugins.py index d75b4a7b1..b55d4d7ee 100644 --- a/src/Tools/salome_plugins.py +++ b/src/Tools/salome_plugins.py @@ -36,7 +36,7 @@ def t_shape_fluid(context): dialog.exec_() if dialog.wasOk(): r1, r2, h1, h2 = dialog.getData() - QMessageBox.about(None, "Building in progress", "building shape, please be patient") + #QMessageBox.about(None, "Building in progress", "building shape, please be patient") shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2) entry = xalome.addToStudy(activeStudy, shape, "T_shape_fluid" ) xalome.displayShape(entry) diff --git a/src/Tools/t_shape_builder.py b/src/Tools/t_shape_builder.py index 2f6bc6ba2..f729f7f6c 100644 --- a/src/Tools/t_shape_builder.py +++ b/src/Tools/t_shape_builder.py @@ -103,9 +103,6 @@ def build_shape(study, r1, r2, h1, h2): v1, l1, arc1, part1 = demidisk(study, r1, a1) v2, l2, arc2, part2 = demidisk(study, r2, a1, 90.0) - geompy.addToStudy(part1, 'part1') - geompy.addToStudy(part2, 'part2') - # --- extrusion des sections --> demi cylindres de travail, pour en extraire les sections utilisées au niveau du Té # et enveloppe cylindrique du cylindre principal @@ -113,10 +110,6 @@ def build_shape(study, r1, r2, h1, h2): demicyl2 = geompy.MakePrismVecH(part2, OZ, h2) arcextru = geompy.MakePrismVecH(arc1, OX, h1) - geompy.addToStudy(demicyl1, 'demicyl1') - geompy.addToStudy(demicyl2, 'demicyl2') - geompy.addToStudy(arcextru, 'arcextru') - # --- plan de coupe à 45° sur le cylindre principal, # section à 45° du cylndre principal, # section du cylindre secondaire par l'enveloppe cylindique du cylindre principal @@ -240,25 +233,21 @@ def build_shape(study, r1, r2, h1, h2): # --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres extru1 = geompy.MakePrismVecH(sect45, OX, h1+10) - geompy.addToStudy(extru1, "extru1") base2 = geompy.MakePartition(faci[5:], [], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) extru2 = geompy.MakePrismVecH(base2, OZ, h2) - geompy.addToStudy(extru2, "extru2") # --- partition et coupe demiDisque = geompy.MakeFaceWires([arc1, l1[0]], 1) demiCylindre = geompy.MakePrismVecH(demiDisque, OX, h1) - #geompy.addToStudy(demiCylindre, "demiCylindre") + box = geompy.MakeBox(0, -2*(r1+h1), -2*(r1+h1), 2*(r1+h1), 2*(r1+h1), 2*(r1+h1)) rot = geompy.MakeRotation(box, OY, 45*math.pi/180.0) - #geompy.addToStudy(rot, "rot") + garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True) - geompy.addToStudy(garder, "garder") raccord = geompy.MakePartition([garder], faci, [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) assemblage = geompy.MakePartition([raccord, extru1, extru2], [], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) - geompy.addToStudy(assemblage, "assemblage") box = geompy.MakeBox(-1, -(r1+r2), -1, h1, r1+r2, h2) geompy.addToStudy(box, "box") diff --git a/src/Tools/t_shape_dialog.py b/src/Tools/t_shape_dialog.py index 6ac37c51f..297be4b21 100644 --- a/src/Tools/t_shape_dialog.py +++ b/src/Tools/t_shape_dialog.py @@ -36,7 +36,6 @@ class TShapeDialog(QtGui.QDialog): self._wasOk = False def accept(self): - print "DATA ACCEPTED" self._wasOk = True QtGui.QDialog.accept(self) @@ -47,25 +46,6 @@ class TShapeDialog(QtGui.QDialog): h2 = self.ui.doubleSpinBox_4.value() return r1, r2, h1, h2 - - #def setupUi(self): - #TShapeDialog_UI.setupUi(self) - #self.handleAcceptWith(self.accept) - #self.handleRejectWith(self.reject) - - #def handleAcceptWith(self,callbackFunction): - #"""This defines the function to be connected to the signal 'accepted()' (click on Ok)""" - #QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), callbackFunction) - - #def handleRejectWith(self,callbackFunction): - #"""This defines the function to be connected to the signal 'rejected()' (click on Cancel)""" - #QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), callbackFunction) - - #def accept(self): - #'''Callback function when dialog is accepted (click Ok)''' - #self._wasOk = True - ## We should test here the validity of values - #QtGui.QDialog.accept(self) def reject(self): self._wasOk = False @@ -74,11 +54,6 @@ class TShapeDialog(QtGui.QDialog): def wasOk(self): return self._wasOk - #def setData(self): - #pass - - #def getData(self): - #pass # ================ # Tests From 8b9db2cd6fe1e07a8601507a8eb4df7a20b35625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Thu, 21 Aug 2014 11:54:39 +0200 Subject: [PATCH 06/63] first modifications for solid part handling --- src/Tools/t_shape_builder.py | 53 ++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/Tools/t_shape_builder.py b/src/Tools/t_shape_builder.py index f729f7f6c..362966acd 100644 --- a/src/Tools/t_shape_builder.py +++ b/src/Tools/t_shape_builder.py @@ -9,7 +9,12 @@ import math import SALOMEDS -def demidisk(study, r1, a1, roty=0): +def demidisk(study, r1, a1, roty=0, solid_thickness=0): # TODO retablir l'épaisseur de solide à 0 par défaut + if solid_thickness < 1e-7: + with_solid = False + else: + with_solid = True + geompy = geomBuilder.New(study) O = geompy.MakeVertex(0, 0, 0) @@ -42,7 +47,20 @@ def demidisk(study, r1, a1, roty=0): arc1 = geompy.MakeArc(v[1], v7, v[3]) l[0] = geompy.MakeLineTwoPnt(v[1], v[3]) face1 = geompy.MakeFaceWires([arc1, l[0]], 1) - part1 = geompy.MakePartition([face1], [l[2], l[4], l[5], l[6], l[7]], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) + + if with_solid: + v0 = geompy.MakeVertex(0, r1 + solid_thickness, 0) + l0 = geompy.MakeLineTwoPnt(v[1], v0) + l2 = geompy.MakeRotation(l0, OX, a1*math.pi/180.0) + l3 = geompy.MakeRotation(l0, OX, math.pi - (a1*math.pi/180.0)) + face2 = geompy.MakeRevolution(l0, OX, a1*math.pi/180.0) + face3 = geompy.MakeRevolution(l2, OX, math.pi - 2*a1*math.pi/180.0) + face4 = geompy.MakeRevolution(l3, OX, a1*math.pi/180.0) + part0 = geompy.MakePartition([face1], [l[2], l[4], l[5], l[6], l[7]], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) + compound1 = geompy.MakeCompound([part0, face2, face3, face4]) + part1 = geompy.MakeGlueEdges(compound1,1e-7) + else: + part1 = geompy.MakePartition([face1], [l[2], l[4], l[5], l[6], l[7]], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) if roty != 0: vrot = [ geompy.MakeRotation(vert, OY, roty*math.pi/180.0) for vert in v ] @@ -109,6 +127,11 @@ def build_shape(study, r1, r2, h1, h2): demicyl1 = geompy.MakePrismVecH(part1, OX, h1) demicyl2 = geompy.MakePrismVecH(part2, OZ, h2) arcextru = geompy.MakePrismVecH(arc1, OX, h1) + + """ + res = geompy.MakeCompound([demicyl1,demicyl2]) + return res + """ # --- plan de coupe à 45° sur le cylindre principal, # section à 45° du cylndre principal, @@ -166,18 +189,21 @@ def build_shape(study, r1, r2, h1, h2): #geompy.addToStudy(plan, "plan%d"%i) section = geompy.MakeSection(plan, arcextru, True) secpart = geompy.MakePartition([section], [sect45, sect90], [], [], geompy.ShapeType["EDGE"], 0, [], 0, True) - #geompy.addToStudy(secpart, "secpart%d"%i) + geompy.addToStudy(secpart, "secpart%d"%i) lsec = geompy.ExtractShapes(secpart, geompy.ShapeType["EDGE"], True) #print "len(lsec)", len(lsec) + + # TODO : revoir ça dans le cas avec solide for l in lsec: pts = geompy.ExtractShapes(l, geompy.ShapeType["VERTEX"], True) if (((geompy.MinDistance(pts[0], p0) < 0.001) and (geompy.MinDistance(pts[1], p1) < 0.001)) or ((geompy.MinDistance(pts[1], p0) < 0.001) and (geompy.MinDistance(pts[0], p1) < 0.001))): curv[i+2] =l - #print "curv_%d OK"%i + print "curv_%d OK"%i break - for i,l in enumerate(curv): - geompy.addToStudyInFather(arcextru, l, "curv%d"%i) + # RNC : commente temporairement + #for i,l in enumerate(curv): + # geompy.addToStudyInFather(arcextru, l, "curv%d"%i) # --- creation des arêtes droites manquantes, des faces et volumes pour les quatre volumes de la jonction @@ -190,8 +216,9 @@ def build_shape(study, r1, r2, h1, h2): edges[5] = geompy.MakeLineTwoPnt(vord45[5], vord90[5]) edges[6] = curv[2] edges[7] = curv[3] - for i,l in enumerate(edges): - geompy.addToStudy( l, "edge%d"%i) + #for i,l in enumerate(edges): + # print i + # geompy.addToStudy( l, "edge%d"%i) ed45 = [None for i in range(8)] ed45[0] = geompy.MakeLineTwoPnt(vord45[0], vord45[2]) @@ -253,7 +280,7 @@ def build_shape(study, r1, r2, h1, h2): geompy.addToStudy(box, "box") final = geompy.MakeCommonList([box, assemblage], True) - # --- Partie infiérieure + # --- Partie inférieure v3, l3, arc3, part3 = demidisk(study, r1, a1, 180.0) geompy.addToStudy(part3,"part3") extru3 = geompy.MakePrismVecH(part3, OX, h1) @@ -267,3 +294,11 @@ def build_shape(study, r1, r2, h1, h2): final = geompy.MakeCompound([compound, compound_mirrored]) return final + +if __name__=="__main__": + """For testing purpose""" + salome.salome_init() + theStudy = salome.myStudy + geompy = geomBuilder.New(theStudy) + res = build_shape(theStudy, 80, 20, 100, 100) + geompy.addToStudy(res, "res") From 7a4a166458b24457d945059a5d98231453bc1756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Wed, 29 Oct 2014 16:30:59 +0100 Subject: [PATCH 07/63] one step further towards solid part management --- src/Tools/t_shape_builder.py | 45 ++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/src/Tools/t_shape_builder.py b/src/Tools/t_shape_builder.py index 362966acd..6c962c6d3 100644 --- a/src/Tools/t_shape_builder.py +++ b/src/Tools/t_shape_builder.py @@ -9,7 +9,7 @@ import math import SALOMEDS -def demidisk(study, r1, a1, roty=0, solid_thickness=0): # TODO retablir l'épaisseur de solide à 0 par défaut +def demidisk(study, r1, a1, roty=0, solid_thickness=0): if solid_thickness < 1e-7: with_solid = False else: @@ -49,8 +49,13 @@ def demidisk(study, r1, a1, roty=0, solid_thickness=0): # TODO retablir l'épais face1 = geompy.MakeFaceWires([arc1, l[0]], 1) if with_solid: - v0 = geompy.MakeVertex(0, r1 + solid_thickness, 0) - l0 = geompy.MakeLineTwoPnt(v[1], v0) + # Vertices + v0 = geompy.MakeVertex(0, r1 + solid_thickness, 0) + v1 = geompy.MakeRotation(v0, OX, a1*math.pi/180.0) + v2 = geompy.MakeRotation(v0, OX, math.pi - (a1*math.pi/180.0)) + v3 = geompy.MakeRotation(v0, OX, math.pi) + v.extend([v0,v1,v3,v2]) # The order is important for use in pointsProjetes + l0 = geompy.MakeLineTwoPnt(v[1], v0) l2 = geompy.MakeRotation(l0, OX, a1*math.pi/180.0) l3 = geompy.MakeRotation(l0, OX, math.pi - (a1*math.pi/180.0)) face2 = geompy.MakeRevolution(l0, OX, a1*math.pi/180.0) @@ -101,7 +106,12 @@ def arcsProjetes(study, vf, face): pass return lord -def build_shape(study, r1, r2, h1, h2): +def build_shape(study, r1, r2, h1, h2, solid_thickness=0): + if solid_thickness < 1e-7: + with_solid = False + else: + with_solid = True + geompy = geomBuilder.New(study) O = geompy.MakeVertex(0, 0, 0) @@ -118,8 +128,8 @@ def build_shape(study, r1, r2, h1, h2): # --- sections droites des deux demi cylindres avec le partionnement - v1, l1, arc1, part1 = demidisk(study, r1, a1) - v2, l2, arc2, part2 = demidisk(study, r2, a1, 90.0) + v1, l1, arc1, part1 = demidisk(study, r1, a1, 0, solid_thickness) + v2, l2, arc2, part2 = demidisk(study, r2, a1, 90.0, solid_thickness) # --- extrusion des sections --> demi cylindres de travail, pour en extraire les sections utilisées au niveau du Té # et enveloppe cylindrique du cylindre principal @@ -135,7 +145,7 @@ def build_shape(study, r1, r2, h1, h2): # --- plan de coupe à 45° sur le cylindre principal, # section à 45° du cylndre principal, - # section du cylindre secondaire par l'enveloppe cylindique du cylindre principal + # section du cylindre secondaire par l'enveloppe cylindrique du cylindre principal plan1 = geompy.MakePlane(O, OX, 4*r1) planr = geompy.MakeRotation(plan1, OY, 45*math.pi/180.0) @@ -171,6 +181,15 @@ def build_shape(study, r1, r2, h1, h2): for i in (0, 2, 4, 5): vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz, True) geompy.addToStudyInFather(sect90, vord90[i], 'vm%d'%i) + if with_solid: + print dz + print "dz*solid_thickness/(r2+solid_thickness) = " + print dz*solid_thickness/(r2+solid_thickness) + for i in (1, 3, 6, 7): + vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz*solid_thickness/(r2+solid_thickness), True) + + res=vord90 + return res # --- création des deux arêtes curvilignes sur l'enveloppe cylindrique du cylindre principal, à la jonction @@ -300,5 +319,13 @@ if __name__=="__main__": salome.salome_init() theStudy = salome.myStudy geompy = geomBuilder.New(theStudy) - res = build_shape(theStudy, 80, 20, 100, 100) - geompy.addToStudy(res, "res") + res = build_shape(theStudy, 80., 20., 100., 100., 10.) + for i,v in enumerate(res): + geompy.addToStudy(v,"v%d"%i) + + #res = demidisk(theStudy, 80, 45, 0, 10) + #geompy.addToStudy(res[3], "res") + #for i,v in enumerate(res[0]): + # geompy.addToStudy(v,"v%d"%i) + #geompy.addToStudy(res, "res") + From 8d2d6670c418eb62d8d573d7f53ddad235bd74f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Fri, 31 Oct 2014 17:07:58 +0100 Subject: [PATCH 08/63] first almost working version with the solid part --- src/Tools/t_shape_builder.py | 173 +++++++++++++++++++++++------------ 1 file changed, 113 insertions(+), 60 deletions(-) diff --git a/src/Tools/t_shape_builder.py b/src/Tools/t_shape_builder.py index 6c962c6d3..95e70fd06 100644 --- a/src/Tools/t_shape_builder.py +++ b/src/Tools/t_shape_builder.py @@ -124,12 +124,101 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): ratio = float(r2)/float(r1) if ratio > (1.0 -seuilmax): a1 = 45.0*(1.0 -ratio)/seuilmax - - - # --- sections droites des deux demi cylindres avec le partionnement + + """ + res = geompy.MakeCompound([demicyl1,demicyl2]) + return res + """ - v1, l1, arc1, part1 = demidisk(study, r1, a1, 0, solid_thickness) - v2, l2, arc2, part2 = demidisk(study, r2, a1, 90.0, solid_thickness) + # --- creation des faces de la jonction + [faci, sect45, arc1, l1, lord90, lord45, edges] = jonction(study, r1, r2,\ + h1, h2, a1) + if with_solid: + [faci_ext, sect45_ext, arc1_ext, l1_ext, lord90_ext, lord45_ext, edges_ext] = jonction(study, r1 + solid_thickness, r2 + solid_thickness,\ + h1, h2, a1) + faces_jonction_ext = [] + for i,l in enumerate(lord90): + faces_jonction_ext.append(geompy.MakeQuad2Edges(lord90[i],lord90_ext[i])) + for i in [1, 3, 6, 7]: + faces_jonction_ext.append(geompy.MakeQuad2Edges(edges[i],edges_ext[i])) + for i,l in enumerate(lord45): + faces_jonction_ext.append(geompy.MakeQuad2Edges(lord45[i],lord45_ext[i])) + + for i,face in enumerate(faces_jonction_ext): + geompy.addToStudy(faces_jonction_ext[i], "faci_ext_%d"%i) + + # --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres + # TODO : ajouter les faces nécessaires à sect45 dans le cas avec solide + if with_solid: + sect45 = geompy.MakePartition([sect45]+faces_jonction_ext[-7:]) + extru1 = geompy.MakePrismVecH(sect45, OX, h1+10) + + #base2 = geompy.MakeCompound(faci[5:]) + #base2 = geompy.MakeGlueEdges(base2, 1e-7) + # RNC : perf + faces_coupe = faci[5:] + if with_solid: + faces_coupe = faci[5:]+faces_jonction_ext[:3] + base2 = geompy.MakePartition(faces_coupe, [], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) + extru2 = geompy.MakePrismVecH(base2, OZ, h2) + + # --- partition et coupe + + if with_solid: + demiDisque = geompy.MakeFaceWires([arc1_ext, l1_ext[0]], 1) + else: + demiDisque = geompy.MakeFaceWires([arc1, l1[0]], 1) + demiCylindre = geompy.MakePrismVecH(demiDisque, OX, h1) + + box = geompy.MakeBox(0, -2*(r1+h1), -2*(r1+h1), 2*(r1+h1), 2*(r1+h1), 2*(r1+h1)) + rot = geompy.MakeRotation(box, OY, 45*math.pi/180.0) + + garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True) + geompy.addToStudy(garder,"garder") + + faces_coupe = faci[:5] + if with_solid: + faces_coupe.extend(faces_jonction_ext[-7:]) + raccord = geompy.MakePartition([garder], faces_coupe, [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) + assemblage = geompy.MakeCompound([raccord, extru1, extru2]) + assemblage = geompy.MakeGlueFaces(assemblage, 1e-7) + # RNC : perf + #assemblage = geompy.MakePartition([raccord, extru1, extru2], [], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) + + #return extru2, garder, raccord + + box = geompy.MakeBox(-1, -(r1+r2+2*solid_thickness), -1, h1, r1+r2+2*solid_thickness, h2) + geompy.addToStudy(box, "box") + final = geompy.MakeCommonList([box, assemblage], True) + + # --- Partie inférieure + v3, l3, arc3, part3 = demidisk(study, r1, a1, 180.0, solid_thickness) + geompy.addToStudy(part3,"part3") + extru3 = geompy.MakePrismVecH(part3, OX, h1) + geompy.addToStudy(extru3,"extru3") + + # --- Symétrie + + compound = geompy.MakeCompound([final, extru3]) + plane = geompy.MakePlane(O,OX,2000) + compound_mirrored = geompy.MakeMirrorByPlane(compound, plane) + final = geompy.MakeCompound([compound, compound_mirrored]) + + return final + + +def jonction(study, r1, r2, h1, h2, a1): + + O = geompy.MakeVertex(0, 0, 0) + OX = geompy.MakeVectorDXDYDZ(1, 0, 0) + OY = geompy.MakeVectorDXDYDZ(0, 1, 0) + OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) + + # --- sections droites des deux demi cylindres avec le partionnement + v1, l1, arc1, part1 = demidisk(study, r1, a1, 0.) + v2, l2, arc2, part2 = demidisk(study, r2, a1, 90.0) + #elems_disk1 = [v1, l1, arc1, part1] + #elems_disk2 = [v2, l2, arc2, part2] # --- extrusion des sections --> demi cylindres de travail, pour en extraire les sections utilisées au niveau du Té # et enveloppe cylindrique du cylindre principal @@ -138,11 +227,6 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): demicyl2 = geompy.MakePrismVecH(part2, OZ, h2) arcextru = geompy.MakePrismVecH(arc1, OX, h1) - """ - res = geompy.MakeCompound([demicyl1,demicyl2]) - return res - """ - # --- plan de coupe à 45° sur le cylindre principal, # section à 45° du cylndre principal, # section du cylindre secondaire par l'enveloppe cylindrique du cylindre principal @@ -156,7 +240,7 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): sect90 = geompy.MakeCommonList([demicyl2, arcextru], True) geompy.addToStudy(sect90, 'sect90') - + # --- liste ordonnée des points projetés sur les deux sections vord45 = pointsProjetes(study, v1, sect45) @@ -177,19 +261,22 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): # --- abaissement des quatre points centraux de la section du cylindre secondaire + #if with_solid: + #dz = -(r2 + solid_thickness)/2.0 + #else: + #dz = -r2/2.0 dz = -r2/2.0 for i in (0, 2, 4, 5): vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz, True) geompy.addToStudyInFather(sect90, vord90[i], 'vm%d'%i) - if with_solid: - print dz - print "dz*solid_thickness/(r2+solid_thickness) = " - print dz*solid_thickness/(r2+solid_thickness) - for i in (1, 3, 6, 7): - vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz*solid_thickness/(r2+solid_thickness), True) - + #if with_solid: + #for i in (1, 3, 6, 7): + #vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz*solid_thickness/(r2+solid_thickness), True) + + """ res=vord90 return res + """ # --- création des deux arêtes curvilignes sur l'enveloppe cylindrique du cylindre principal, à la jonction @@ -235,9 +322,9 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): edges[5] = geompy.MakeLineTwoPnt(vord45[5], vord90[5]) edges[6] = curv[2] edges[7] = curv[3] - #for i,l in enumerate(edges): - # print i - # geompy.addToStudy( l, "edge%d"%i) + for i,l in enumerate(edges): + print i + geompy.addToStudy( l, "edge%d"%i) ed45 = [None for i in range(8)] ed45[0] = geompy.MakeLineTwoPnt(vord45[0], vord45[2]) @@ -276,43 +363,7 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): for i,f in enumerate(faci): geompy.addToStudy(f, "faci_%d"%i) - # --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres - - extru1 = geompy.MakePrismVecH(sect45, OX, h1+10) - - base2 = geompy.MakePartition(faci[5:], [], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) - extru2 = geompy.MakePrismVecH(base2, OZ, h2) - - # --- partition et coupe - - demiDisque = geompy.MakeFaceWires([arc1, l1[0]], 1) - demiCylindre = geompy.MakePrismVecH(demiDisque, OX, h1) - - box = geompy.MakeBox(0, -2*(r1+h1), -2*(r1+h1), 2*(r1+h1), 2*(r1+h1), 2*(r1+h1)) - rot = geompy.MakeRotation(box, OY, 45*math.pi/180.0) - - garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True) - raccord = geompy.MakePartition([garder], faci, [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) - assemblage = geompy.MakePartition([raccord, extru1, extru2], [], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) - - box = geompy.MakeBox(-1, -(r1+r2), -1, h1, r1+r2, h2) - geompy.addToStudy(box, "box") - final = geompy.MakeCommonList([box, assemblage], True) - - # --- Partie inférieure - v3, l3, arc3, part3 = demidisk(study, r1, a1, 180.0) - geompy.addToStudy(part3,"part3") - extru3 = geompy.MakePrismVecH(part3, OX, h1) - geompy.addToStudy(extru3,"extru3") - - # --- Symétrie - - compound = geompy.MakeCompound([final, extru3]) - plane = geompy.MakePlane(O,OX,2000) - compound_mirrored = geompy.MakeMirrorByPlane(compound, plane) - final = geompy.MakeCompound([compound, compound_mirrored]) - - return final + return faci, sect45, arc1, l1, lord90, lord45, edges if __name__=="__main__": """For testing purpose""" @@ -320,12 +371,14 @@ if __name__=="__main__": theStudy = salome.myStudy geompy = geomBuilder.New(theStudy) res = build_shape(theStudy, 80., 20., 100., 100., 10.) + """ for i,v in enumerate(res): geompy.addToStudy(v,"v%d"%i) - + """ + #res = demidisk(theStudy, 80, 45, 0, 10) #geompy.addToStudy(res[3], "res") #for i,v in enumerate(res[0]): # geompy.addToStudy(v,"v%d"%i) - #geompy.addToStudy(res, "res") + geompy.addToStudy(res, "res") From 0939da642972e2f4ed12e54ea2172b4c9f156f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Mon, 3 Nov 2014 09:54:48 +0100 Subject: [PATCH 09/63] first fully working version, not optimised though --- src/Tools/t_shape_builder.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Tools/t_shape_builder.py b/src/Tools/t_shape_builder.py index 95e70fd06..dfaa4a4d8 100644 --- a/src/Tools/t_shape_builder.py +++ b/src/Tools/t_shape_builder.py @@ -131,11 +131,12 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): """ # --- creation des faces de la jonction - [faci, sect45, arc1, l1, lord90, lord45, edges] = jonction(study, r1, r2,\ - h1, h2, a1) + [faci, sect45, arc1, l1, lord90, lord45, edges, arcextru] = jonction(study, r1, r2,\ + h1, h2, a1) if with_solid: - [faci_ext, sect45_ext, arc1_ext, l1_ext, lord90_ext, lord45_ext, edges_ext] = jonction(study, r1 + solid_thickness, r2 + solid_thickness,\ - h1, h2, a1) + [faci_ext, sect45_ext, arc1_ext, l1_ext, \ + lord90_ext, lord45_ext, edges_ext, arcextru_ext] = jonction(study, r1 + solid_thickness, r2 + solid_thickness,\ + h1, h2, a1) faces_jonction_ext = [] for i,l in enumerate(lord90): faces_jonction_ext.append(geompy.MakeQuad2Edges(lord90[i],lord90_ext[i])) @@ -150,7 +151,10 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): # --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres # TODO : ajouter les faces nécessaires à sect45 dans le cas avec solide if with_solid: - sect45 = geompy.MakePartition([sect45]+faces_jonction_ext[-7:]) + sect45 = geompy.MakeCompound([sect45]+faces_jonction_ext[-3:]) + sect45 = geompy.MakeGlueEdges(sect45, 1e-7) + + #return sect45, faces_jonction_ext[-3:] extru1 = geompy.MakePrismVecH(sect45, OX, h1+10) #base2 = geompy.MakeCompound(faci[5:]) @@ -179,7 +183,7 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): faces_coupe = faci[:5] if with_solid: faces_coupe.extend(faces_jonction_ext[-7:]) - raccord = geompy.MakePartition([garder], faces_coupe, [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) + raccord = geompy.MakePartition([garder], faces_coupe + [arcextru], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) assemblage = geompy.MakeCompound([raccord, extru1, extru2]) assemblage = geompy.MakeGlueFaces(assemblage, 1e-7) # RNC : perf @@ -363,7 +367,7 @@ def jonction(study, r1, r2, h1, h2, a1): for i,f in enumerate(faci): geompy.addToStudy(f, "faci_%d"%i) - return faci, sect45, arc1, l1, lord90, lord45, edges + return faci, sect45, arc1, l1, lord90, lord45, edges, arcextru if __name__=="__main__": """For testing purpose""" From 8a6296ea1ac1d48153e6cfd552da90f42cdae302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Tue, 4 Nov 2014 16:56:54 +0100 Subject: [PATCH 10/63] some cleaning and update of the dialog box --- src/Tools/CMakeLists.txt | 29 +++++++ .../{salome_plugins.py => geom_plugins.py} | 4 +- src/Tools/{ => t_shape}/t_shape_builder.py | 71 ++++++---------- src/Tools/{ => t_shape}/t_shape_dialog.py | 3 +- src/Tools/{ => t_shape}/t_shape_dialog.ui | 82 +++++++++++++++---- src/Tools/{ => t_shape}/t_shape_dialog_ui.py | 31 +++++-- 6 files changed, 146 insertions(+), 74 deletions(-) create mode 100644 src/Tools/CMakeLists.txt rename src/Tools/{salome_plugins.py => geom_plugins.py} (96%) rename src/Tools/{ => t_shape}/t_shape_builder.py (90%) rename src/Tools/{ => t_shape}/t_shape_dialog.py (95%) rename src/Tools/{ => t_shape}/t_shape_dialog.ui (61%) rename src/Tools/{ => t_shape}/t_shape_dialog_ui.py (74%) diff --git a/src/Tools/CMakeLists.txt b/src/Tools/CMakeLists.txt new file mode 100644 index 000000000..435c5fdae --- /dev/null +++ b/src/Tools/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (C) 2012-2014 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +ADD_SUBDIRECTORY(t_shape) + +# scripts / static +SET(plugin_SCRIPTS + geom_plugins.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_GEOM_INSTALL_PLUGINS}) diff --git a/src/Tools/salome_plugins.py b/src/Tools/geom_plugins.py similarity index 96% rename from src/Tools/salome_plugins.py rename to src/Tools/geom_plugins.py index b55d4d7ee..00ad4f149 100644 --- a/src/Tools/salome_plugins.py +++ b/src/Tools/geom_plugins.py @@ -35,9 +35,9 @@ def t_shape_fluid(context): # gui and used to create the shape of the tube. dialog.exec_() if dialog.wasOk(): - r1, r2, h1, h2 = dialog.getData() + r1, r2, h1, h2, thickness = dialog.getData() #QMessageBox.about(None, "Building in progress", "building shape, please be patient") - shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2) + shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2, thickness) entry = xalome.addToStudy(activeStudy, shape, "T_shape_fluid" ) xalome.displayShape(entry) #if dialog.wasOk(): diff --git a/src/Tools/t_shape_builder.py b/src/Tools/t_shape/t_shape_builder.py similarity index 90% rename from src/Tools/t_shape_builder.py rename to src/Tools/t_shape/t_shape_builder.py index dfaa4a4d8..0321c3616 100644 --- a/src/Tools/t_shape_builder.py +++ b/src/Tools/t_shape/t_shape_builder.py @@ -7,6 +7,7 @@ import GEOM from salome.geom import geomBuilder import math import SALOMEDS +import time def demidisk(study, r1, a1, roty=0, solid_thickness=0): @@ -47,26 +48,31 @@ def demidisk(study, r1, a1, roty=0, solid_thickness=0): arc1 = geompy.MakeArc(v[1], v7, v[3]) l[0] = geompy.MakeLineTwoPnt(v[1], v[3]) face1 = geompy.MakeFaceWires([arc1, l[0]], 1) - + part1 = geompy.MakePartition([face1], [l[2], l[4], l[5], l[6], l[7]], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) + if with_solid: - # Vertices + # Add some faces corresponding to the solid layer outside + # the fluid part + + # --- Vertices v0 = geompy.MakeVertex(0, r1 + solid_thickness, 0) v1 = geompy.MakeRotation(v0, OX, a1*math.pi/180.0) v2 = geompy.MakeRotation(v0, OX, math.pi - (a1*math.pi/180.0)) v3 = geompy.MakeRotation(v0, OX, math.pi) v.extend([v0,v1,v3,v2]) # The order is important for use in pointsProjetes + # --- Lines l0 = geompy.MakeLineTwoPnt(v[1], v0) l2 = geompy.MakeRotation(l0, OX, a1*math.pi/180.0) l3 = geompy.MakeRotation(l0, OX, math.pi - (a1*math.pi/180.0)) + # --- Faces face2 = geompy.MakeRevolution(l0, OX, a1*math.pi/180.0) face3 = geompy.MakeRevolution(l2, OX, math.pi - 2*a1*math.pi/180.0) face4 = geompy.MakeRevolution(l3, OX, a1*math.pi/180.0) - part0 = geompy.MakePartition([face1], [l[2], l[4], l[5], l[6], l[7]], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) - compound1 = geompy.MakeCompound([part0, face2, face3, face4]) + # --- Compound of the "fluid part" of the divided disk and the additional faces + compound1 = geompy.MakeCompound([part1, face2, face3, face4]) + # --- Glue edges part1 = geompy.MakeGlueEdges(compound1,1e-7) - else: - part1 = geompy.MakePartition([face1], [l[2], l[4], l[5], l[6], l[7]], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) - + if roty != 0: vrot = [ geompy.MakeRotation(vert, OY, roty*math.pi/180.0) for vert in v ] lrot = [ geompy.MakeRotation(lin, OY, roty*math.pi/180.0) for lin in l ] @@ -85,7 +91,6 @@ def pointsProjetes(study, vref, face): for i,v in enumerate(vproj): dist = [ (geompy.MinDistance(v, vr), j) for j,vr in enumerate(vref) ] dist.sort() - #print dist if dist[0][0] < 1.e-3: vord[dist[0][1]] = vface[i] return vord @@ -107,6 +112,8 @@ def arcsProjetes(study, vf, face): return lord def build_shape(study, r1, r2, h1, h2, solid_thickness=0): + """ Builds the final shape """ + if solid_thickness < 1e-7: with_solid = False else: @@ -124,16 +131,13 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): ratio = float(r2)/float(r1) if ratio > (1.0 -seuilmax): a1 = 45.0*(1.0 -ratio)/seuilmax - - """ - res = geompy.MakeCompound([demicyl1,demicyl2]) - return res - """ - # --- creation des faces de la jonction + # --- Creation of the jonction faces [faci, sect45, arc1, l1, lord90, lord45, edges, arcextru] = jonction(study, r1, r2,\ h1, h2, a1) if with_solid: + # The same code is executed again with different external radiuses in order + # to get the needed faces and edges to build the solid layer of the pipe [faci_ext, sect45_ext, arc1_ext, l1_ext, \ lord90_ext, lord45_ext, edges_ext, arcextru_ext] = jonction(study, r1 + solid_thickness, r2 + solid_thickness,\ h1, h2, a1) @@ -149,17 +153,12 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): geompy.addToStudy(faces_jonction_ext[i], "faci_ext_%d"%i) # --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres - # TODO : ajouter les faces nécessaires à sect45 dans le cas avec solide if with_solid: sect45 = geompy.MakeCompound([sect45]+faces_jonction_ext[-3:]) sect45 = geompy.MakeGlueEdges(sect45, 1e-7) - #return sect45, faces_jonction_ext[-3:] extru1 = geompy.MakePrismVecH(sect45, OX, h1+10) - #base2 = geompy.MakeCompound(faci[5:]) - #base2 = geompy.MakeGlueEdges(base2, 1e-7) - # RNC : perf faces_coupe = faci[5:] if with_solid: faces_coupe = faci[5:]+faces_jonction_ext[:3] @@ -177,22 +176,22 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): box = geompy.MakeBox(0, -2*(r1+h1), -2*(r1+h1), 2*(r1+h1), 2*(r1+h1), 2*(r1+h1)) rot = geompy.MakeRotation(box, OY, 45*math.pi/180.0) + # NOTE: The following Cut takes almost half of the total execution time garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True) geompy.addToStudy(garder,"garder") faces_coupe = faci[:5] if with_solid: faces_coupe.extend(faces_jonction_ext[-7:]) + t4=time.time() raccord = geompy.MakePartition([garder], faces_coupe + [arcextru], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) assemblage = geompy.MakeCompound([raccord, extru1, extru2]) assemblage = geompy.MakeGlueFaces(assemblage, 1e-7) - # RNC : perf - #assemblage = geompy.MakePartition([raccord, extru1, extru2], [], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) - #return extru2, garder, raccord - box = geompy.MakeBox(-1, -(r1+r2+2*solid_thickness), -1, h1, r1+r2+2*solid_thickness, h2) geompy.addToStudy(box, "box") + + # NOTE: This operation takes about 1/4 of the total execution time final = geompy.MakeCommonList([box, assemblage], True) # --- Partie inférieure @@ -212,6 +211,9 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): def jonction(study, r1, r2, h1, h2, a1): + """ Builds the jonction faces and + returns what is needed to build the whole pipe + """ O = geompy.MakeVertex(0, 0, 0) OX = geompy.MakeVectorDXDYDZ(1, 0, 0) @@ -221,9 +223,7 @@ def jonction(study, r1, r2, h1, h2, a1): # --- sections droites des deux demi cylindres avec le partionnement v1, l1, arc1, part1 = demidisk(study, r1, a1, 0.) v2, l2, arc2, part2 = demidisk(study, r2, a1, 90.0) - #elems_disk1 = [v1, l1, arc1, part1] - #elems_disk2 = [v2, l2, arc2, part2] - + # --- extrusion des sections --> demi cylindres de travail, pour en extraire les sections utilisées au niveau du Té # et enveloppe cylindrique du cylindre principal @@ -264,23 +264,11 @@ def jonction(study, r1, r2, h1, h2, a1): geompy.addToStudyInFather(sect90, l, 'l%d'%i) # --- abaissement des quatre points centraux de la section du cylindre secondaire - - #if with_solid: - #dz = -(r2 + solid_thickness)/2.0 - #else: - #dz = -r2/2.0 + dz = -r2/2.0 for i in (0, 2, 4, 5): vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz, True) geompy.addToStudyInFather(sect90, vord90[i], 'vm%d'%i) - #if with_solid: - #for i in (1, 3, 6, 7): - #vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz*solid_thickness/(r2+solid_thickness), True) - - """ - res=vord90 - return res - """ # --- création des deux arêtes curvilignes sur l'enveloppe cylindrique du cylindre principal, à la jonction @@ -301,9 +289,7 @@ def jonction(study, r1, r2, h1, h2, a1): secpart = geompy.MakePartition([section], [sect45, sect90], [], [], geompy.ShapeType["EDGE"], 0, [], 0, True) geompy.addToStudy(secpart, "secpart%d"%i) lsec = geompy.ExtractShapes(secpart, geompy.ShapeType["EDGE"], True) - #print "len(lsec)", len(lsec) - # TODO : revoir ça dans le cas avec solide for l in lsec: pts = geompy.ExtractShapes(l, geompy.ShapeType["VERTEX"], True) if (((geompy.MinDistance(pts[0], p0) < 0.001) and (geompy.MinDistance(pts[1], p1) < 0.001)) or @@ -311,9 +297,6 @@ def jonction(study, r1, r2, h1, h2, a1): curv[i+2] =l print "curv_%d OK"%i break - # RNC : commente temporairement - #for i,l in enumerate(curv): - # geompy.addToStudyInFather(arcextru, l, "curv%d"%i) # --- creation des arêtes droites manquantes, des faces et volumes pour les quatre volumes de la jonction diff --git a/src/Tools/t_shape_dialog.py b/src/Tools/t_shape/t_shape_dialog.py similarity index 95% rename from src/Tools/t_shape_dialog.py rename to src/Tools/t_shape/t_shape_dialog.py index 297be4b21..192684be0 100644 --- a/src/Tools/t_shape_dialog.py +++ b/src/Tools/t_shape/t_shape_dialog.py @@ -44,8 +44,9 @@ class TShapeDialog(QtGui.QDialog): r2 = self.ui.doubleSpinBox_2.value() h1 = self.ui.doubleSpinBox_3.value() h2 = self.ui.doubleSpinBox_4.value() + thickness = self.ui.doubleSpinBox_5.value() - return r1, r2, h1, h2 + return r1, r2, h1, h2, thickness def reject(self): self._wasOk = False diff --git a/src/Tools/t_shape_dialog.ui b/src/Tools/t_shape/t_shape_dialog.ui similarity index 61% rename from src/Tools/t_shape_dialog.ui rename to src/Tools/t_shape/t_shape_dialog.ui index 7a9a52471..8caa136b5 100644 --- a/src/Tools/t_shape_dialog.ui +++ b/src/Tools/t_shape/t_shape_dialog.ui @@ -6,15 +6,15 @@ 0 0 - 321 - 242 + 349 + 283 Dialog - - + + @@ -58,14 +58,28 @@ - - - - Build solid part - - + + + + + + Build solid part + + + + + + + Solid thickness + + + + + + + - + Qt::Horizontal @@ -86,12 +100,12 @@ accept() - 248 - 254 + 205 + 241 157 - 274 + 250 @@ -102,12 +116,44 @@ reject() - 316 - 260 + 205 + 241 - 286 - 274 + 214 + 250 + + + + + checkBox + clicked(bool) + label_5 + setEnabled(bool) + + + 89 + 184 + + + 107 + 205 + + + + + checkBox + clicked(bool) + doubleSpinBox_5 + setEnabled(bool) + + + 140 + 178 + + + 277 + 212 diff --git a/src/Tools/t_shape_dialog_ui.py b/src/Tools/t_shape/t_shape_dialog_ui.py similarity index 74% rename from src/Tools/t_shape_dialog_ui.py rename to src/Tools/t_shape/t_shape_dialog_ui.py index c4353e11f..b034e677a 100644 --- a/src/Tools/t_shape_dialog_ui.py +++ b/src/Tools/t_shape/t_shape_dialog_ui.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 't_shape_dialog.ui' # -# Created: Thu Jun 19 11:13:43 2014 +# Created: Tue Nov 4 16:52:09 2014 # by: PyQt4 UI code generator 4.9.6 # # WARNING! All changes made in this file will be lost! @@ -26,9 +26,9 @@ except AttributeError: class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName(_fromUtf8("Dialog")) - Dialog.resize(331, 242) - self.verticalLayout = QtGui.QVBoxLayout(Dialog) - self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + Dialog.resize(349, 283) + self.gridLayout_3 = QtGui.QGridLayout(Dialog) + self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3")) self.gridLayout = QtGui.QGridLayout() self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.doubleSpinBox_2 = QtGui.QDoubleSpinBox(Dialog) @@ -55,19 +55,30 @@ class Ui_Dialog(object): self.label_4 = QtGui.QLabel(Dialog) self.label_4.setObjectName(_fromUtf8("label_4")) self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1) - self.verticalLayout.addLayout(self.gridLayout) + self.gridLayout_3.addLayout(self.gridLayout, 0, 0, 1, 1) + self.gridLayout_2 = QtGui.QGridLayout() + self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) self.checkBox = QtGui.QCheckBox(Dialog) self.checkBox.setObjectName(_fromUtf8("checkBox")) - self.verticalLayout.addWidget(self.checkBox) + self.gridLayout_2.addWidget(self.checkBox, 0, 0, 1, 1) + self.label_5 = QtGui.QLabel(Dialog) + self.label_5.setObjectName(_fromUtf8("label_5")) + self.gridLayout_2.addWidget(self.label_5, 1, 0, 1, 1) + self.doubleSpinBox_5 = QtGui.QDoubleSpinBox(Dialog) + self.doubleSpinBox_5.setObjectName(_fromUtf8("doubleSpinBox_5")) + self.gridLayout_2.addWidget(self.doubleSpinBox_5, 1, 1, 1, 1) + self.gridLayout_3.addLayout(self.gridLayout_2, 1, 0, 1, 1) self.buttonBox = QtGui.QDialogButtonBox(Dialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) - self.verticalLayout.addWidget(self.buttonBox) + self.gridLayout_3.addWidget(self.buttonBox, 2, 0, 1, 1) self.retranslateUi(Dialog) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject) + QtCore.QObject.connect(self.checkBox, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.label_5.setEnabled) + QtCore.QObject.connect(self.checkBox, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.doubleSpinBox_5.setEnabled) QtCore.QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): @@ -77,8 +88,8 @@ class Ui_Dialog(object): self.label_2.setText(_translate("Dialog", "Small pipe radius", None)) self.label_4.setText(_translate("Dialog", "Small pipe height", None)) self.checkBox.setText(_translate("Dialog", "Build solid part", None)) - - + self.label_5.setText(_translate("Dialog", "Solid thickness", None)) + if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) @@ -88,3 +99,5 @@ if __name__ == "__main__": Dialog.show() sys.exit(app.exec_()) + + From c926071d44bc85bc98f7020e6c46f2b75f3ff928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Tue, 4 Nov 2014 17:12:26 +0100 Subject: [PATCH 11/63] missing file --- src/Tools/t_shape/CMakeLists.txt | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/Tools/t_shape/CMakeLists.txt diff --git a/src/Tools/t_shape/CMakeLists.txt b/src/Tools/t_shape/CMakeLists.txt new file mode 100644 index 000000000..35cc00554 --- /dev/null +++ b/src/Tools/t_shape/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (C) 2012-2014 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# --- scripts --- + +# scripts / static +SET(plugin_SCRIPTS + t_shape_builder.py + t_shape_dialog.py + t_shape_dialog.ui + t_shape_dialog_ui.py + ) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/t_shape) From 665709c95c31a43cca0fbebfdad37b3b4f95fc05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20N=C3=A9d=C3=A9lec?= Date: Wed, 5 Nov 2014 16:08:27 +0100 Subject: [PATCH 12/63] update of tests, some cleaning of addToStudy instructions and small GUI fix --- src/Tools/t_shape/t_shape_builder.py | 71 ++++++++-------------------- src/Tools/t_shape/t_shape_dialog.py | 2 + 2 files changed, 21 insertions(+), 52 deletions(-) diff --git a/src/Tools/t_shape/t_shape_builder.py b/src/Tools/t_shape/t_shape_builder.py index 0321c3616..09a818b29 100644 --- a/src/Tools/t_shape/t_shape_builder.py +++ b/src/Tools/t_shape/t_shape_builder.py @@ -7,8 +7,6 @@ import GEOM from salome.geom import geomBuilder import math import SALOMEDS -import time - def demidisk(study, r1, a1, roty=0, solid_thickness=0): if solid_thickness < 1e-7: @@ -149,9 +147,6 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): for i,l in enumerate(lord45): faces_jonction_ext.append(geompy.MakeQuad2Edges(lord45[i],lord45_ext[i])) - for i,face in enumerate(faces_jonction_ext): - geompy.addToStudy(faces_jonction_ext[i], "faci_ext_%d"%i) - # --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres if with_solid: sect45 = geompy.MakeCompound([sect45]+faces_jonction_ext[-3:]) @@ -178,27 +173,23 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): # NOTE: The following Cut takes almost half of the total execution time garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True) - geompy.addToStudy(garder,"garder") faces_coupe = faci[:5] if with_solid: faces_coupe.extend(faces_jonction_ext[-7:]) - t4=time.time() raccord = geompy.MakePartition([garder], faces_coupe + [arcextru], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) assemblage = geompy.MakeCompound([raccord, extru1, extru2]) assemblage = geompy.MakeGlueFaces(assemblage, 1e-7) box = geompy.MakeBox(-1, -(r1+r2+2*solid_thickness), -1, h1, r1+r2+2*solid_thickness, h2) - geompy.addToStudy(box, "box") # NOTE: This operation takes about 1/4 of the total execution time final = geompy.MakeCommonList([box, assemblage], True) # --- Partie inférieure + v3, l3, arc3, part3 = demidisk(study, r1, a1, 180.0, solid_thickness) - geompy.addToStudy(part3,"part3") extru3 = geompy.MakePrismVecH(part3, OX, h1) - geompy.addToStudy(extru3,"extru3") # --- Symétrie @@ -214,6 +205,7 @@ def jonction(study, r1, r2, h1, h2, a1): """ Builds the jonction faces and returns what is needed to build the whole pipe """ + geompy = geomBuilder.New(study) O = geompy.MakeVertex(0, 0, 0) OX = geompy.MakeVectorDXDYDZ(1, 0, 0) @@ -237,32 +229,20 @@ def jonction(study, r1, r2, h1, h2, a1): plan1 = geompy.MakePlane(O, OX, 4*r1) planr = geompy.MakeRotation(plan1, OY, 45*math.pi/180.0) - geompy.addToStudy(planr, 'planr') sect45 = geompy.MakeCommonList([demicyl1, planr], True) - geompy.addToStudy(sect45, 'sect45') - sect90 = geompy.MakeCommonList([demicyl2, arcextru], True) - geompy.addToStudy(sect90, 'sect90') - + # --- liste ordonnée des points projetés sur les deux sections vord45 = pointsProjetes(study, v1, sect45) vord90 = pointsProjetes(study, v2, sect90) - for i,v in enumerate(vord45): - geompy.addToStudyInFather(sect45, v, 'v%d'%i) - for i,v in enumerate(vord90): - geompy.addToStudyInFather(sect90, v, 'v%d'%i) # --- identification des projections des trois arcs de cercle, sur les deux sections. - + lord45 = arcsProjetes(study, vord45, sect45) lord90 = arcsProjetes(study, vord90, sect90) - for i,l in enumerate(lord45): - geompy.addToStudyInFather(sect45, l, 'l%d'%i) - for i,l in enumerate(lord90): - geompy.addToStudyInFather(sect90, l, 'l%d'%i) - + # --- abaissement des quatre points centraux de la section du cylindre secondaire dz = -r2/2.0 @@ -309,10 +289,7 @@ def jonction(study, r1, r2, h1, h2, a1): edges[5] = geompy.MakeLineTwoPnt(vord45[5], vord90[5]) edges[6] = curv[2] edges[7] = curv[3] - for i,l in enumerate(edges): - print i - geompy.addToStudy( l, "edge%d"%i) - + ed45 = [None for i in range(8)] ed45[0] = geompy.MakeLineTwoPnt(vord45[0], vord45[2]) ed45[1] = geompy.MakeLineTwoPnt(vord45[0], vord45[1]) @@ -322,9 +299,7 @@ def jonction(study, r1, r2, h1, h2, a1): ed45[5] = geompy.MakeLineTwoPnt(vord45[4], vord45[5]) ed45[6] = geompy.MakeLineTwoPnt(vord45[0], vord45[4]) ed45[7] = geompy.MakeLineTwoPnt(vord45[2], vord45[5]) - for i,l in enumerate(ed45): - geompy.addToStudyInFather(sect45, l, "ed45_%d"%i) - + ed90 = [None for i in range(8)] ed90[0] = geompy.MakeLineTwoPnt(vord90[0], vord90[2]) ed90[1] = geompy.MakeLineTwoPnt(vord90[0], vord90[1]) @@ -334,8 +309,6 @@ def jonction(study, r1, r2, h1, h2, a1): ed90[5] = geompy.MakeLineTwoPnt(vord90[4], vord90[5]) ed90[6] = geompy.MakeLineTwoPnt(vord90[0], vord90[4]) ed90[7] = geompy.MakeLineTwoPnt(vord90[2], vord90[5]) - for i,l in enumerate(ed90): - geompy.addToStudyInFather(sect90, l, "ed90_%d"%i) faci = [] faci.append(geompy.MakeFaceWires([ed45[6], edges[0], ed90[6], edges[4]], 0)) @@ -343,13 +316,11 @@ def jonction(study, r1, r2, h1, h2, a1): faci.append(geompy.MakeFaceWires([ed45[2], edges[4], ed90[2], edges[6]], 0)) faci.append(geompy.MakeFaceWires([ed45[5], edges[4], ed90[5], edges[5]], 0)) faci.append(geompy.MakeFaceWires([ed45[4], edges[5], ed90[4], edges[7]], 0)) - faci.append(geompy.MakeFaceWires([ed90[0], ed90[6], ed90[5], ed90[7]], 0)) - faci.append(geompy.MakeFaceWires([ed90[1], ed90[6], ed90[2], lord90[0]], 0)) - faci.append(geompy.MakeFaceWires([ed90[2], ed90[5], ed90[4], lord90[1]], 0)) - faci.append(geompy.MakeFaceWires([ed90[3], ed90[7], ed90[4], lord90[2]], 0)) - for i,f in enumerate(faci): - geompy.addToStudy(f, "faci_%d"%i) - + faci.append(geompy.MakeFaceWires([ed90[0], ed90[6], ed90[5], ed90[7]], 0)) + faci.append(geompy.MakeFaceWires([ed90[1], ed90[6], ed90[2], lord90[0]], 0)) + faci.append(geompy.MakeFaceWires([ed90[2], ed90[5], ed90[4], lord90[1]], 0)) + faci.append(geompy.MakeFaceWires([ed90[3], ed90[7], ed90[4], lord90[2]], 0)) + return faci, sect45, arc1, l1, lord90, lord45, edges, arcextru if __name__=="__main__": @@ -357,15 +328,11 @@ if __name__=="__main__": salome.salome_init() theStudy = salome.myStudy geompy = geomBuilder.New(theStudy) - res = build_shape(theStudy, 80., 20., 100., 100., 10.) - """ - for i,v in enumerate(res): - geompy.addToStudy(v,"v%d"%i) - """ - - #res = demidisk(theStudy, 80, 45, 0, 10) - #geompy.addToStudy(res[3], "res") - #for i,v in enumerate(res[0]): - # geompy.addToStudy(v,"v%d"%i) - geompy.addToStudy(res, "res") + for r1 in [1, 100, 10000]: + for r2 in [0.75*r1, 0.3*r1, 0.1*r1]: + for thickness in [(r1-r2)/10.0, (r1-r2) /2.0, 0.75*(r1-r2)]: + h1 = r1 * 1.5 + h2 = h1 + res = build_shape(theStudy, r1, r2, h1, h2, thickness) + geompy.addToStudy(res, "res_%f_%f_%f"%(r1,r2, thickness)) diff --git a/src/Tools/t_shape/t_shape_dialog.py b/src/Tools/t_shape/t_shape_dialog.py index 192684be0..ce6032994 100644 --- a/src/Tools/t_shape/t_shape_dialog.py +++ b/src/Tools/t_shape/t_shape_dialog.py @@ -34,6 +34,8 @@ class TShapeDialog(QtGui.QDialog): self.ui.setupUi(self) self.show() self._wasOk = False + self.ui.doubleSpinBox_5.setEnabled(False) + self.ui.label_5.setEnabled(False) def accept(self): self._wasOk = True From 9d1e80b15d4c744cb20282024fec444bfffc09d1 Mon Sep 17 00:00:00 2001 From: vsr Date: Mon, 19 Oct 2015 11:23:44 +0300 Subject: [PATCH 13/63] Set development flag to 1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a28f2af2..828cfb7f4 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ SET(${PROJECT_NAME_UC}_MINOR_VERSION 7) SET(${PROJECT_NAME_UC}_PATCH_VERSION 0) SET(${PROJECT_NAME_UC}_VERSION ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION}) -SET(${PROJECT_NAME_UC}_VERSION_DEV 0) +SET(${PROJECT_NAME_UC}_VERSION_DEV 1) # Find KERNEL # =========== From d3fc195109e7e4eb1d479e2ff72f8aa636ce5d75 Mon Sep 17 00:00:00 2001 From: vsr Date: Wed, 21 Oct 2015 15:47:45 +0300 Subject: [PATCH 14/63] C++11 compatibility --- src/OCC2VTK/GEOM_EdgeSource.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OCC2VTK/GEOM_EdgeSource.cxx b/src/OCC2VTK/GEOM_EdgeSource.cxx index cc01eb7e8..a76c4e86f 100755 --- a/src/OCC2VTK/GEOM_EdgeSource.cxx +++ b/src/OCC2VTK/GEOM_EdgeSource.cxx @@ -126,11 +126,11 @@ void GEOM_EdgeSource::OCC2VTK (const TopoDS_Edge& theEdge, pt2.Transform(edgeTransf); } - float aCoord1[3] = {pt1.X(), pt1.Y(), pt1.Z()}; + float aCoord1[3] = {(float)pt1.X(), (float)pt1.Y(), (float)pt1.Z()}; vtkIdType anIds[2]; anIds[0] = thePts->InsertNextPoint(aCoord1); - float aCoord2[3] = {pt2.X(), pt2.Y(), pt2.Z()}; + float aCoord2[3] = {(float)pt2.X(), (float)pt2.Y(), (float)pt2.Z()}; anIds[1] = thePts->InsertNextPoint(aCoord2); thePolyData->InsertNextCell(VTK_LINE,2,anIds); @@ -156,11 +156,11 @@ void GEOM_EdgeSource::OCC2VTK (const TopoDS_Edge& theEdge, pt2.Transform(edgeTransf); } - float aCoord1[3] = {pt1.X(), pt1.Y(), pt1.Z()}; + float aCoord1[3] = {(float)pt1.X(), (float)pt1.Y(), (float)pt1.Z()}; vtkIdType anIds[2]; anIds[0] = thePts->InsertNextPoint(aCoord1); - float aCoord2[3] = {pt2.X(), pt2.Y(), pt2.Z()}; + float aCoord2[3] = {(float)pt2.X(), (float)pt2.Y(), (float)pt2.Z()}; anIds[1] = thePts->InsertNextPoint(aCoord2); thePolyData->InsertNextCell(VTK_LINE,2,anIds); @@ -226,7 +226,7 @@ void GEOM_EdgeSource::OCC2VTK (const TopoDS_Edge& theEdge, // Add points and segments, composing the arrow Standard_Real cosinus, sinus, Tg = tan(anAngle); - float coord[3] = {xo, yo, zo}; + float coord[3] = {(float)xo, (float)yo, (float)zo}; vtkIdType ptLoc = thePts->InsertNextPoint(coord); vtkIdType ptFirst = 0; From d075248eebd06a3d3baae97b4c14fd91cf713af8 Mon Sep 17 00:00:00 2001 From: ysn Date: Mon, 19 Oct 2015 11:13:40 +0300 Subject: [PATCH 15/63] Documentation update --- .../GEOM/input/check_compound_of_blocks.doc | 11 +++---- .../GEOM/input/check_self_intersections.doc | 33 ++++++++++++------- doc/salome/gui/GEOM/input/dependency_tree.doc | 2 +- .../projection_on_cylinder_operation.doc | 8 ++--- .../GEOM/input/shape_statistics_operation.doc | 10 +++--- .../gui/GEOM/input/working_with_groups.doc | 4 +-- 6 files changed, 39 insertions(+), 29 deletions(-) diff --git a/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc b/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc index 486184871..5b95a8723 100644 --- a/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc +++ b/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc @@ -3,7 +3,7 @@ \page check_compound_of_blocks_page Check Compound of Blocks This operation checks whether a shape is a compound of glued blocks -and tries to improve the shape to make it include only valid blocks. +and improves the shape to include only valid blocks. \image html measures10.png @@ -29,16 +29,15 @@ In this dialog: - Not connected; - Extra or degenerated edge. - Incriminated Sub-shapes field outputs the list of sub-shapes that cause problem. -- \b Apply and Apply and Close buttons launch an improving process -and publish a result shape which includes valid blocks only. The -improving process tries to - - remove seam edges and degenerated edges of surfaces of revolution; +- \b Apply and Apply and Close buttons launch the improvement process +and publish the result shape, which includes valid blocks only. The +algorithm tries to: + - remove seam and degenerated edges from surfaces of revolution; - re-approximate surfaces to exclude singularities on boundaries; - unite edges and faces; - glue faces. - \n TUI Command: geompy.CheckCompoundOfBlocks(Compound, theIsUseC1 = False, theAngTolerance = 1.e-12). Checks if the shape is a valid compound of blocks. If it is true, then the validity flag diff --git a/doc/salome/gui/GEOM/input/check_self_intersections.doc b/doc/salome/gui/GEOM/input/check_self_intersections.doc index c92695a10..8533274e2 100644 --- a/doc/salome/gui/GEOM/input/check_self_intersections.doc +++ b/doc/salome/gui/GEOM/input/check_self_intersections.doc @@ -2,7 +2,7 @@ \page check_self_intersections_page Detect Self-intersections -\n To Detect Self-intersections in the Main Menu select +\n To Detect Self-intersections, select in the Main Menu Inspection - > Detect Self-intersections. There are two ways to check self-intersections. @@ -40,24 +40,35 @@ See also a \ref tui_check_self_intersections_page "TUI example". \anchor check_self_intersections_fast

Fast intersection

-This operations allows to quickly detect self-interferences of the given shape by means of algorithm based on mesh intersections. +This operation allows quickly detecting self-interferences of the given shape using the algorithm based on mesh intersections. + +The algorithm works on the face level, i.e. it computes only face-to-face intersections. No additional intersection types are computed. + +This can be useful to detect all intersections between subshapes of type "surface" in an assembly. +The result quality will depend on the tesselation quality. However, small deflection values can significantly decrease the performance of the algorithm. +Nevertheless, the performance of Fast Intersect algorithm is much higher than that of the topological intersection. \image html measures13.png -This algorithm works on the faces level, i.e. it computes only face-to-face intersections. No additional types of intersections is computed. -This case can be useful in order to detect all the intersections between the subshapes of type "surface" inside assembly. -Quality of result will depend on the quality of tesselation (managed via the deflection parameter). However, small values of deflection can -significantly decrease performance of the algorithm. -Nevertheless, performance of Fast Intersect algorithm is much higher than topological intersection. +In this dialog: + +- \b Object - the checked object. \b Selection button allows picking it in the viewer or in the object browser. +- Deflection coefficient - a linear deflection coefficient that defines the tesselation quality. If theDeflection <= 0, default deflection 0.001 is used. +- Detect gaps with tolerance specifies the distance between shapes used for detecting gaps: + - if theTolerance <= 0, the algorithm detects intersections; + - if theTolerance > 0, the algorithm detects gapss. +- Compute self-intersections button performs the computation. +- \b Summary section contains the general report about self-intersections of the object and/or errors that occurred during the computation. +- \b Self-intersections list contains the list of detected self-intersections. Select the intersection to show Sub-shapes in the field to the right. +- \b Apply and Apply and Close buttons store the interferences selected in the Self-intersections list box in the study for further analysis. +If no interferences are selected, all of them are published in the study. Each interference is published as a child compound of the source shape and contains a couple of intersecting sub-shapes. \n Result: Boolean. \n TUI Command: geompy.CheckSelfIntersectionsFast(theShape, theDeflection, theTolerance), \n where: \n \em theShape is the shape checked for validity. \n -\em theDeflection is a linear deflection coefficient that specifies quality of tesselation. If theDeflection <= 0, default deflection 0.001 is used. -\em theTolerance Specifies a distance between shapes used for detecting gaps: - - if theTolerance <= 0, algorithm detects intersections; - - if theTolerance > 0, algorithm detects gaps. +\em theDeflection that specifies the quality of tesselation. +\em theTolerance Specifies the distance between shapes used for detecting gaps. See also a \ref tui_check_self_intersections_fast_page "TUI example". diff --git a/doc/salome/gui/GEOM/input/dependency_tree.doc b/doc/salome/gui/GEOM/input/dependency_tree.doc index 40e1a2ac4..b9bbe9566 100644 --- a/doc/salome/gui/GEOM/input/dependency_tree.doc +++ b/doc/salome/gui/GEOM/input/dependency_tree.doc @@ -28,7 +28,7 @@ It is also possible to select an object(s) directly in the "Dependency Tree" vie All necessary parameters of Dependency Tree Viewer can be edited in the \ref pref_dependency_tree "Preferences". -\note This functionality is available only if GUI module is builded with Graphics view (set option SALOME_USE_GRAPHICSVIEW to ON when building GUI module). +\note This functionality is available only if the GUI module is built with Graphics view (option SALOME_USE_GRAPHICSVIEW is ON when building GUI module).
\anchor dependency_tree_nodes_anchor

Nodes

diff --git a/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc b/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc index 5cc528fb6..3d8978d8d 100644 --- a/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc +++ b/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc @@ -18,14 +18,14 @@ the angle of the projection start. - Length angle where the total length of the wire should be projected. If it is unchecked the projection is not scaled and the natural wire length is kept for the projection. -- Rotation angle the desired angle between the tangent vector to -the first curve at the first point of the theObject's projection in 2D space -and U-direction of cylinder's 2D space. +- Rotation angle the angle between the tangent vector to +the first curve at the first point of the object projection in 2D space +and U-direction of the cylinder in 2D space. - \ref restore_presentation_parameters_page "Advanced options". \image html proj_on_cyl_dlg.png -\n The following figure explains meaning of each input angle: +\n The following figure explains the meaning of each input angle: \image html proj_on_cyl_angles.png "Input angles of projection on the cylinder" diff --git a/doc/salome/gui/GEOM/input/shape_statistics_operation.doc b/doc/salome/gui/GEOM/input/shape_statistics_operation.doc index 991d103b5..d1fb6fe25 100644 --- a/doc/salome/gui/GEOM/input/shape_statistics_operation.doc +++ b/doc/salome/gui/GEOM/input/shape_statistics_operation.doc @@ -12,19 +12,19 @@ In this dialog: - "Selected objects" standard selection box allows selecting one or more geometrical objects. - "Type" combo-box with the following items: "Edges length", "Faces area", "Solids volume". -\note "Type" combo-box includes only parameters applied to the currently selected shape (e.g. "Solids volume" will not be available for face or shell being selected); multiple selection is processed correspondingly (i.e. only types applicable for all selected shapes will be available). +\note "Type" combo-box includes only parameters applied to the currently selected shape (e.g. "Solids volume" will not be available for a selected face or shell); multiple selection is processed correspondingly (i.e. only types applicable for all selected shapes will be available). - "Number of intervals" spin box is used to specify number of distribution histogram ranges. -- "Scalar range" checkable group box that, when switched ON, allows specifying custom values range used for plotting and creating groups. -\note By default, "Scalar range" controls is empty; pressing "Compute" button allows automatic computing initial range of the chosen parameter. This is needed as computation of the parameters range can be time-consuming for large or complex models. In case of multiple selection, scalar range is computed as common from all selected shapes. +- "Scalar range" checkable group box, when switched ON, allows specifying custom values range used for plotting and creating groups. +\note By default, "Scalar range" controls are empty; pressing "Compute" button allows automatically computing the initial range of the chosen parameter. This is necessary as the computation of the parameters range can be time-consuming for large or complex models. In case of multiple selection, the scalar range is computed for all selected shapes. - "Plot" button opens or uses an opened Plot2d viewer and plots the distribution histogram for the selected shape(s). -- "Create groups" button allows creating a groups according to the currently specified parameters. The groups names will include numerical values of the range, e.g. "Edges_length_0-20", "Edges_length_20-40", etc. Empty groups are not created. +- "Create groups" button allows creating groups according to the currently specified parameters. The group names will include numerical values of the range, e.g. "Edges_length_0-20", "Edges_length_20-40", etc. Empty groups are not created. - Close dialog box, by pressing Close button. -\note This functionality is available only if GUI module is builded with Plot 2D Viewer (set option SALOME_USE_PLOT2DVIEWER to ON when building GUI module). +\note This functionality is available only if GUI module is built with Plot 2D Viewer (option SALOME_USE_PLOT2DVIEWER is ON when building GUI module). */ diff --git a/doc/salome/gui/GEOM/input/working_with_groups.doc b/doc/salome/gui/GEOM/input/working_with_groups.doc index 852047dfb..aa9951260 100644 --- a/doc/salome/gui/GEOM/input/working_with_groups.doc +++ b/doc/salome/gui/GEOM/input/working_with_groups.doc @@ -101,8 +101,8 @@ In order to filter out some entities: The entities, which satisfy the entered filtering parameters, will be automatically highlighted in the 3D viewer. -\b Plot button into "Filter" group box provides an access -to the \ref shape_statistics_operation_page "Shape Statistics" functionality with simplified look-n-feel: +\b Plot button gives access +to the \ref shape_statistics_operation_page "Shape Statistics" functionality with a simplified look-and-feel: \image html shape_statistics_simple.png From e6bcaa307fef3efd962a0959d0830ccb7dc659fb Mon Sep 17 00:00:00 2001 From: skv Date: Tue, 3 Nov 2015 11:38:55 +0300 Subject: [PATCH 16/63] 0023193: [CEA] Show sub-shapes with given tolerance --- doc/salome/gui/GEOM/images/inspect_object.png | Bin 29765 -> 36455 bytes .../gui/GEOM/images/inspect_object2.png | Bin 0 -> 30954 bytes .../GEOM/input/inspect_object_operation.doc | 51 +- doc/salome/gui/GEOM/input/tui_test_all.doc | 3 + idl/GEOM_Gen.idl | 31 + src/GEOMGUI/GEOM_msg_en.ts | 30 +- src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 100 ++ src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 22 + src/GEOMUtils/GEOMUtils.cxx | 55 ++ src/GEOMUtils/GEOMUtils.hxx | 40 + src/GEOM_I/GEOM_IShapesOperations_i.cc | 74 ++ src/GEOM_I/GEOM_IShapesOperations_i.hh | 6 + src/GEOM_SWIG/GEOM_TestAll.py | 6 + src/GEOM_SWIG/geomBuilder.py | 51 + src/RepairGUI/CMakeLists.txt | 2 + src/RepairGUI/RepairGUI.cxx | 2 +- src/RepairGUI/RepairGUI_InspectObjectDlg.cxx | 872 +++++++++++++++--- src/RepairGUI/RepairGUI_InspectObjectDlg.h | 60 +- 18 files changed, 1232 insertions(+), 173 deletions(-) create mode 100644 doc/salome/gui/GEOM/images/inspect_object2.png mode change 100755 => 100644 doc/salome/gui/GEOM/input/inspect_object_operation.doc diff --git a/doc/salome/gui/GEOM/images/inspect_object.png b/doc/salome/gui/GEOM/images/inspect_object.png index 09d90d0699337e4314fb5409490731e33a5af3f9..23065bd2edba206a5ae4212b65474085ed186a46 100644 GIT binary patch literal 36455 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 literal 29765 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 diff --git a/doc/salome/gui/GEOM/images/inspect_object2.png b/doc/salome/gui/GEOM/images/inspect_object2.png new file mode 100644 index 0000000000000000000000000000000000000000..121e15275478299d874fe512cb54dee0cac7ec42 GIT binary patch literal 30954 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%0D|8+115)4opNSKjr zf9f#1c{8=}O8ORuj}CA7=}fbOqTX*HTCu^!XtcLWjP{yjfC z!$Et9laFDj@sE`0+)q6(%Fl$x($dQoimXSe9VVYfVXg7NS-3N6L}n=$b-j#H-{jVL7=pN2<*TXg{plDO2GDmkG4YB zSK9Jkg$@YZyuOR#D|}c>EEH6V2EaxDy9gBtMfgO?CZ;HnIwcy=CmJMi zn~OyBfFr4_scD?A%E`;@^XmV|N7T;3+}NiS5Td!c^gIL<445ohuKU?8>bnLb@&lEbLk96JDQS2_d5~690toC&6{6+w7;4nBaR$)m*$=%7`i|BW3O5|8ZzzQROocdcLIu%co6UPwl_PoG@7jxEL z6p!D}zlcp6Z+u<#dy)Pj~67XO6J+2j0vhra~S8Y!;TfYRnxtPf%d`=FS6zb<$Z z^xaE2dU#HPKVQ`6y%dof#gBp$GlPyr!yV9LyYj>eZ$5caO_-d-AJW@ZBDx+{>O!xD%Q zJw`}=2FGu1N*H#P=~3L$7g5$de6+vO@Fn9<6w{!_B@R0X5ja)6DB;k?yP*$X-z++A zv0pWQ5X8v;Fv^v~9ftWgfTO^4T#A&GFZ_@zQY!R6Vp9oX>@M;P(d5N+29%<~`myTZ zFk7jUj$c}&-eyO;wOa17^Lbw;lrO&4zr_*sxM5nRpu2_n>$ zMG$e1waoZ+c&Z3+f~hZf=&;eRnRXk{V@%xX&b~Eov`aJ;mtnoLHwsV9=3X>tjdu3* zluofIx(Ruh=vwCSO9yy_1$ZRqG#a!l2vNb5Mi&w z7gC1C!A0%)8X62e#h#>86oXW|3uwQp4~5Ni%*+~yX5nAaMhXoY zrb|A3VkISI^}X?3@j)StpfTg)s3^mvp8UhNOm>%}-pe9iiIvsv_w6RvBbNOJFgF8J zDZoM;#U6R7435rq5yMNr_taJMxEq!F@_)Sy+s_l<;W=qZN8C&HGKNl!*u`1#OG@$g z=Ft#<0gnDX+>92V#e#OThE4aJ{trU`4{uJ$002T*`v2n2G2kIspa{tw0fU%vUbZ1Dei^FL?#eZYUt{C~aqpG*8tXa48S|D5IbbN}|u|J>j212(h- zOkEs<;ek*juH)Vw(se?gs8zsF90?K?Hs|M$GcNP~dwBlSxqk~A6Os4+dh8`?S6oc> zc&%!DR<2odyIZ08=2muesOls0z+T1fRrIx*Ls|8BXthVp?&iUb6t}#`=VC%MZ@J{9 za1dkn%`J);Z-^PrH5Pg_MNn4?=`BQ>vy{lf-#0$K0z4g1?Q!A-`H|&B08pQklSt8C z{NuNA-h83m0XuoB1*brHotU5bi|4I-*r3DtMhP*c-soVMu zX3g{5Xb8d`>hajGHzVJW)#1xJ-o+ohONyjzybd`x`-&P4Bz1E_i7qkv(5u&Df;iXulOLR<3>IdzvX84XLo`P&qirEhU zhz&3}BgSCIJ0!CoVQ-lnYTZDgPy_{cpSf4}mYO|8)3!7x?7sic``uC=sg84I9xdPq zEs?WcKuh9fVih*=@n0wt4TD4}_gj~N>2B(RY<4M%_{75>{ zGqzZ~VbHqC>e`pr=lnEouv5W;YvUWiCo+1hpZcomDr|fKsf@Q(|$!5-M%C*R6NeqTAur)+$#VuR59533vdGXTJP2x*)PM50-ioQ>s zV5p0KtZW-xyZEf>lST(Gk*u55XHE+8aCQ@`6(m%q0iNBm5}mr?Eine~Rg lmLA71Z%#I~Em@)Vv08}UsHUx&a=`NP{{i>_jbH!( literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/input/inspect_object_operation.doc b/doc/salome/gui/GEOM/input/inspect_object_operation.doc old mode 100755 new mode 100644 index 0650bd47b..bff2fbd64 --- a/doc/salome/gui/GEOM/input/inspect_object_operation.doc +++ b/doc/salome/gui/GEOM/input/inspect_object_operation.doc @@ -6,12 +6,41 @@ This operation allows browsing the contents of the selected shape. To Inspect Object, in the Main Menu select Measures - > Inspect Object. -\image html inspect_object.png +The dialog can be used in two modes. The first one is a tree view mode: +\image html inspect_object.png "Dialog in the tree view mode" -In this dialog: +This is a default mode that allows to inspect an object in the form of tree +starting from the shape itself. Its children are its direct sub-shapes that +have they own children as sub-shapes etc. till most very base sub-shapes, +i.e. vertices. + +The second mode is a filtering one. It is activated when the user selects +Tolerance filter check box: +\image html inspect_object2.png "Dialog in the filtering mode" + +In this mode the user can check the type of sub-shapes to work with using +the radio-buttons. The type can be either \b Vertex, \b Edge or \b Face. +Then the user choses a tolerance criterion to be applied to filter out +sub-shapes. It is possible to chose one of the following values: +- \b > - greater than (default value) +- \b >= - greater than or equal to +- \b < - lower than +- \b <= - lower than or equal to + +The last parameter to be chosen is the tolerance value. The result is the shapes +of a certain type that satisfy the defined tolerance criterion. E.g. if the user +chooses \b Face, criterion \b > and tolerance value equal to \b 1.e-6 the faces +with the tolerance greater than \b 1.e-6 are displayed. + +It is possible to set maximal and minimal value of the tolerance using the +buttons Max value and Min value. These values are displayed in +the labels Max : and Min : + +In this dialog never mind of its mode it is possible to: - Click on the "selection" button and select an object to inspect in the Object Browser or in the viewer. -- Show/hide sub-shape(s) in the 3D viewer, by pressing “eye” icon in the first column of the tree view. -- Show/hide all sub-shapes in the 3D viewer, by pressing “eye” icon in the first column of the tree view header. +- Show/hide sub-shape(s) in the 3D viewer, by pressing "eye" icon in the first column of the tree view. +- Show/hide all sub-shapes in the tree, by pressing "eye" icon in the first column of the tree view header or + by pressing Show all/Hide all buttons. - Rename the selected sub-shape by double-clicking on the item or pressing key. - Show the selected sub-shape(s) in the 3D viewer by pressing Show Selected button. - Show the selected sub-shape(s) in the 3D viewer and erase all currently shown objects by pressing Show Only Selected button. @@ -19,4 +48,18 @@ In this dialog: - Publish the selected sub-shapes in the study, by pressing Publish Selected button. - Close dialog box, by pressing Close button. +\n TUI Command: + +A command to filter sub-shapes is defined: + +geompy.GetSubShapesWithTolerance(theShape, theShapeType, theCondition, theTolerance), \n +where \n +\em theShape is the shape to be exploded. \n +\em theShapeType is the type of sub-shapes to be returned. Can have + the values \b GEOM.FACE, \b GEOM.EDGE and \b GEOM.VERTEX only.\n +\em theCondition is the condition type (the value of GEOM.comparison_condition emuneration).\n +\em theTolerance is the tolerance filter. + +See also a \ref swig_GetSubShapesWithTolerance "TUI example". + */ diff --git a/doc/salome/gui/GEOM/input/tui_test_all.doc b/doc/salome/gui/GEOM/input/tui_test_all.doc index f2407ca29..5ed1334a0 100644 --- a/doc/salome/gui/GEOM/input/tui_test_all.doc +++ b/doc/salome/gui/GEOM/input/tui_test_all.doc @@ -102,6 +102,9 @@ \until geompy.RestoreSubShapes(Partition1) \anchor swig_GetSubShapeEdgeSorted +\until geompy.GetSubShapeEdgeSorted(Sketcher3d_2, p3, "OrderedEdges") + +\anchor swig_GetSubShapesWithTolerance \until print "DONE" */ diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 98af123bd..830fcc398 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -209,6 +209,17 @@ module GEOM SI_ALL // all interferences }; + /** + * This enumeration represents comparison conditions. + */ + enum comparison_condition + { + CC_GT, ///< Greater then + CC_GE, ///< Greater then or equal to + CC_LT, ///< Less then + CC_LE ///< Less then or equal to + }; + /*! * \brief Object creation parameters * @@ -2747,6 +2758,26 @@ module GEOM ListOfGO GetSubShapeEdgeSorted (in GEOM_Object theShape, in GEOM_Object theStartPoint); + /*! + * \brief Return the list of subshapes that satisfies a certain tolerance + * criterion. The user defines the type of shapes to be returned, the + * condition and the tolerance value. The operation is defined for + * faces, edges and vertices only. E.g. for theShapeType FACE, theCondition + * CC_GT and theTolerance 1.e-7 this method returns all faces of theShape + * that have tolerances greater then 1.e7. + * + * \param theShape the shape to be exploded + * \param theShapeType the type of shapes to be returned. Can have the + * values FACE, EDGE and VERTEX only. + * \param theCondition the condition type. + * \param theTolerance the tolerance filter. + * \return the list of shapes that satisfy the conditions. + */ + ListOfGO GetSubShapesWithTolerance(in GEOM_Object theShape, + in short theShapeType, + in comparison_condition theCondition, + in double theTolerance); + }; // # GEOM_IBlocksOperations: diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 491d964f8..2f225edbd 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -5440,6 +5440,14 @@ shells and solids on the other hand. GEOM_DIM_AXES Dimensions along local axes + + SHOW_ALL_BTN + Show all + + + HIDE_ALL_BTN + Hide all + GeometryGUI @@ -6507,14 +6515,6 @@ Number of sketch points too small REMOVE_BTN Remove - - SHOW_ALL_BTN - Show all - - - HIDE_ALL_BTN - Hide all - DISTANCE_ITEM Distance @@ -7231,7 +7231,19 @@ Do you want to create new material? Main shape - GEOM_INSPECT_OBJECT_SHOW + GEOM_INSPECT_TOLERANCE_FILTER + Tolerance filter + + + GEOM_INSPECT_RESET_MIN + Min value + + + GEOM_INSPECT_RESET_MAX + Max value + + + GEOM_INSPECT_OBJECT_SHOW Show Selected diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index 96c8e49b1..3ed4513ec 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -3062,6 +3062,106 @@ Handle(TColStd_HSequenceOfTransient) return aSeq; } +//============================================================================= +/*! + * GetSubShapesWithTolerance + */ +//============================================================================= +Handle(TColStd_HSequenceOfTransient) + GEOMImpl_IShapesOperations::GetSubShapesWithTolerance + (const Handle(GEOM_Object) &theShape, + const Standard_Integer theShapeType, + const GEOMUtils::ComparisonCondition theCondition, + const Standard_Real theTolerance) +{ + if (theShape.IsNull()) { + SetErrorCode("NULL GEOM object"); + return NULL; + } + + TopoDS_Shape aShape = theShape->GetValue(); + + if (aShape.IsNull()) { + SetErrorCode("NULL Shape"); + return NULL; + } + + if (theShapeType != TopAbs_FACE && theShapeType != TopAbs_EDGE && + theShapeType != TopAbs_VERTEX && aShape.ShapeType() >= theShapeType) { + SetErrorCode("Invalid shape type"); + return NULL; + } + + TopTools_IndexedMapOfShape anIndices; + TopTools_MapOfShape aMapFence; + TopExp_Explorer anExp(aShape, + (TopAbs_ShapeEnum) theShapeType); + Handle(TColStd_HSequenceOfInteger) anIDs = new TColStd_HSequenceOfInteger; + + TopExp::MapShapes(aShape, anIndices); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aSubShape = anExp.Current(); + + if (aMapFence.Add(aSubShape)) { + // Compute tolerance + Standard_Real aTolerance = -1.; + + switch (aSubShape.ShapeType()) { + case TopAbs_FACE: + aTolerance = BRep_Tool::Tolerance(TopoDS::Face(aSubShape)); + break; + case TopAbs_EDGE: + aTolerance = BRep_Tool::Tolerance(TopoDS::Edge(aSubShape)); + break; + case TopAbs_VERTEX: + aTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(aSubShape)); + break; + default: + break; + } + + if (aTolerance < 0.) { + continue; + } + + // Compare the tolerance with reference value. + if (GEOMUtils::IsFitCondition (theCondition, aTolerance, theTolerance)) { + anIDs->Append(anIndices.FindIndex(aSubShape)); + } + } + } + + if (anIDs->IsEmpty()) { + SetErrorCode("Empty sequence of sub-shapes"); + return NULL; + } + + // Get objects by indices. + TCollection_AsciiString anAsciiList; + Handle(TColStd_HSequenceOfTransient) aSeq = + getObjectsShapesOn(theShape, anIDs, anAsciiList); + + if (aSeq.IsNull() || aSeq->IsEmpty()) { + SetErrorCode("Empty sequence of edges"); + return NULL; + } + + // Make a Python command + Handle(GEOM_Object) anObj = + Handle(GEOM_Object)::DownCast(aSeq->Value(1)); + Handle(GEOM_Function) aFunction = anObj->GetLastFunction(); + + GEOM::TPythonDump(aFunction) + << "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapesWithTolerance(" + << theShape << ", " << theShapeType << ", " << theCondition << ", " + << theTolerance << ")"; + + SetErrorCode(OK); + + return aSeq; +} + //======================================================================= //function : getShapesOnSurfaceIDs /*! diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 795a55d1b..5078a386a 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -33,6 +33,7 @@ #include "GEOM_IOperations.hxx" #include "GEOMAlgo_State.hxx" +#include "GEOMUtils.hxx" #include #include @@ -448,6 +449,27 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations GetSubShapeEdgeSorted (const Handle(GEOM_Object) &theShape, const Handle(GEOM_Object) &theStartPoint); + /*! + * \brief Return the list of subshapes that satisfies a certain tolerance + * criterion. The user defines the type of shapes to be returned, the + * condition and the tolerance value. The operation is defined for + * faces, edges and vertices only. E.g. for theShapeType FACE, theCondition + * CC_GT and theTolerance 1.e-7 this method returns all faces of theShape + * that have tolerances greater then 1.e7. + * + * \param theShape the shape to be exploded + * \param theShapeType the type of shapes to be returned. Can have the + * values FACE, EDGE and VERTEX only. + * \param theCondition the condition type. + * \param theTolerance the tolerance filter. + * \return the list of shapes that satisfy the conditions. + */ + Handle(TColStd_HSequenceOfTransient) GetSubShapesWithTolerance + (const Handle(GEOM_Object) &theShape, + const Standard_Integer theShapeType, + const GEOMUtils::ComparisonCondition theCondition, + const Standard_Real theTolerance); + private: Handle(GEOM_Object) MakeShape (std::list theShapes, const Standard_Integer theObjectType, diff --git a/src/GEOMUtils/GEOMUtils.cxx b/src/GEOMUtils/GEOMUtils.cxx index 3e0b18977..c359c2567 100644 --- a/src/GEOMUtils/GEOMUtils.cxx +++ b/src/GEOMUtils/GEOMUtils.cxx @@ -104,6 +104,9 @@ #define STD_SORT_ALGO 1 +#define DEFAULT_TOLERANCE_TOLERANCE 1.e-02 +#define DEFAULT_MAX_TOLERANCE_TOLERANCE 1.e-06 + // When the following macro is defined, ShapeFix_ShapeTolerance function is used to set max tolerance of curve // in GEOMUtils::FixShapeCurves function; otherwise less restrictive BRep_Builder::UpdateEdge/UpdateVertex // approach is used @@ -1287,3 +1290,55 @@ bool GEOMUtils::IsOpenPath(const TopoDS_Shape &theShape) return isOpen; } + +//======================================================================= +//function : CompareToleranceValues +//purpose : +//======================================================================= +int GEOMUtils::CompareToleranceValues(const double theTolShape, + const double theTolRef) +{ + const double aTolTol = Min(DEFAULT_MAX_TOLERANCE_TOLERANCE, + theTolRef*DEFAULT_TOLERANCE_TOLERANCE); + + int aResult = 0; + + if (theTolShape < theTolRef - aTolTol) { + aResult = -1; + } else if (theTolShape > theTolRef + aTolTol) { + aResult = 1; + } + + return aResult; +} + +//======================================================================= +//function : IsFitCondition +//purpose : +//======================================================================= +bool GEOMUtils::IsFitCondition(const ComparisonCondition theCondition, + const double theTolShape, + const double theTolRef) +{ + const int aCompValue = CompareToleranceValues(theTolShape, theTolRef); + bool isFit = false; + + switch (theCondition) { + case CC_GT: + isFit = aCompValue == 1; + break; + case GEOMUtils::CC_GE: + isFit = aCompValue != -1; + break; + case GEOMUtils::CC_LT: + isFit = aCompValue == -1; + break; + case GEOMUtils::CC_LE: + isFit = aCompValue != 1; + break; + default: + break; + } + + return isFit; +} diff --git a/src/GEOMUtils/GEOMUtils.hxx b/src/GEOMUtils/GEOMUtils.hxx index 8ffa25be2..184bc9703 100644 --- a/src/GEOMUtils/GEOMUtils.hxx +++ b/src/GEOMUtils/GEOMUtils.hxx @@ -55,6 +55,16 @@ inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2) namespace GEOMUtils { + /** + * This enumeration represents comparison conditions. + */ + enum ComparisonCondition { + CC_GT, ///< Greater then + CC_GE, ///< Greater then or equal to + CC_LT, ///< Less then + CC_LE ///< Less then or equal to + }; + typedef std::vector NodeLinks; typedef std::map LevelInfo; typedef std::vector LevelsList; @@ -341,6 +351,36 @@ namespace GEOMUtils */ Standard_EXPORT bool IsOpenPath(const TopoDS_Shape &theShape); + /** + * This function compares two tolerances. The shape tolerance (the first + * argument) is considered less than the reference tolerance (the second + * argument) if theTolShape < theTolRef - Tolerance(theTolRef). theTolShape is + * considered greater than theTolRef if theTolShape > theTolRef + + * Tolerance(theTolRef). Otherwise these tolerances are equal. + * Tolerance(theTolRef) = theTolRef*DEFAULT_TOLERANCE_TOLERANCE. But this value + * should not be greated than DEFAULT_MAX_TOLERANCE_TOLERANCE. + * + * \param theTolShape the shape tolerance + * \param theTolRef the reference tolerance + * \return -1 if theTolShape is less than theTolRef; 1 if theTolShape is greater + * than theTolRef; 0 if they are equal + */ + Standard_EXPORT int CompareToleranceValues(const double theTolShape, + const double theTolRef); + + /** + * Check if the comarison of tolerances fit the condition. The comparison of + * tolerances is performed using the function CompareToleranceValues. + * + * \param theCondition the condition + * \param theTolShape the shape tolerance + * \param theTolRef the reference tolerance + * \return true if the shape tolerance fits the condition; false otherwise. + */ + Standard_EXPORT bool IsFitCondition(const ComparisonCondition theCondition, + const double theTolShape, + const double theTolRef); + }; #endif diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.cc b/src/GEOM_I/GEOM_IShapesOperations_i.cc index 1e88b88f9..7561d9a16 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@ -35,6 +35,35 @@ #include #include +/** + * This function converts GEOM::comparison_condition type into + * GEOMUtils::ComparisonCondition type. + * + * \param theCondition the condition of GEOM::comparison_condition type + * \return the condition of GEOMUtils::ComparisonCondition type. + */ +static GEOMUtils::ComparisonCondition ComparisonCondition + (const GEOM::comparison_condition theCondition) +{ + GEOMUtils::ComparisonCondition aResult = GEOMUtils::CC_GT; + + switch (theCondition) { + case GEOM::CC_GE: + aResult = GEOMUtils::CC_GE; + break; + case GEOM::CC_LT: + aResult = GEOMUtils::CC_LT; + break; + case GEOM::CC_LE: + aResult = GEOMUtils::CC_LE; + break; + default: + break; + } + + return aResult; +} + //============================================================================= /*! * constructor: @@ -2156,3 +2185,48 @@ GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSubShapeEdgeSorted return aSeq._retn(); } + +//============================================================================= +/*! + * GetSubShapesWithTolerance + */ +//============================================================================= +GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSubShapesWithTolerance + (GEOM::GEOM_Object_ptr theShape, + CORBA::Short theShapeType, + GEOM::comparison_condition theCondition, + CORBA::Double theTolerance) +{ + GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference objects + Handle(GEOM_Object) aShape = GetObjectImpl(theShape); + + if (aShape.IsNull()) { + return aSeq._retn(); + } + + //Get Shapes On Shape + const GEOMUtils::ComparisonCondition aCondition = + ComparisonCondition(theCondition); + Handle(TColStd_HSequenceOfTransient) aHSeq = + GetOperations()->GetSubShapesWithTolerance + (aShape, theShapeType, aCondition, theTolerance); + + if (!GetOperations()->IsDone() || aHSeq.IsNull()) + return aSeq._retn(); + + const Standard_Integer aLength = aHSeq->Length(); + Standard_Integer i; + + aSeq->length(aLength); + + for (i = 1; i <= aLength; i++) { + aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i))); + } + + return aSeq._retn(); +} diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.hh b/src/GEOM_I/GEOM_IShapesOperations_i.hh index f8dba7caf..0f36a38c3 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@ -300,6 +300,12 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i : GEOM::ListOfGO* GetSubShapeEdgeSorted (GEOM::GEOM_Object_ptr theShape, GEOM::GEOM_Object_ptr theStartPoint); + GEOM::ListOfGO* GetSubShapesWithTolerance + (GEOM::GEOM_Object_ptr theShape, + CORBA::Short theShapeType, + GEOM::comparison_condition theCondition, + CORBA::Double theTolerance); + ::GEOMImpl_IShapesOperations* GetOperations() { return (::GEOMImpl_IShapesOperations*)GetImpl(); } }; diff --git a/src/GEOM_SWIG/GEOM_TestAll.py b/src/GEOM_SWIG/GEOM_TestAll.py index 683918508..ea862293f 100644 --- a/src/GEOM_SWIG/GEOM_TestAll.py +++ b/src/GEOM_SWIG/GEOM_TestAll.py @@ -584,5 +584,11 @@ def TestAll (geompy, math): geompy.GetSubShapeEdgeSorted(Sketcher3d_1, p2, "OrderedEdges") geompy.GetSubShapeEdgeSorted(Sketcher3d_2, p3, "OrderedEdges") + # GetSubShapesWithTolerance + geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_GT, 1.e-8, "gt") + geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_GE, 1.e-7, "ge") + geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_LT, 2.e-7, "lt") + geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_LE, 1.e-7, "le") + print "DONE" diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 46573011e..16e9ea4ca 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -6574,6 +6574,57 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): self._autoPublish(ListObj, theName, "SortedEdges") return ListObj + ## + # Return the list of subshapes that satisfies a certain tolerance + # criterion. The user defines the type of shapes to be returned, the + # condition and the tolerance value. The operation is defined for + # faces, edges and vertices only. E.g. for theShapeType FACE, + # theCondition GEOM::CC_GT and theTolerance 1.e-7 this method returns + # all faces of theShape that have tolerances greater then 1.e7. + # + # @param theShape the shape to be exploded + # @param theShapeType the type of sub-shapes to be returned (see + # ShapeType()). Can have the values FACE, EDGE and VERTEX only. + # @param theCondition the condition type (see GEOM::comparison_condition). + # @param theTolerance the tolerance filter. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # @return the list of shapes that satisfy the conditions. + # + # @ref swig_GetSubShapesWithTolerance "Example" + @ManageTransactions("ShapesOp") + def GetSubShapesWithTolerance(self, theShape, theShapeType, + theCondition, theTolerance, theName=None): + """ + Return the list of subshapes that satisfies a certain tolerance + criterion. The user defines the type of shapes to be returned, the + condition and the tolerance value. The operation is defined for + faces, edges and vertices only. E.g. for theShapeType FACE, + theCondition GEOM::CC_GT and theTolerance 1.e-7 this method returns + all faces of theShape that have tolerances greater then 1.e7. + + Parameters: + theShape the shape to be exploded + theShapeType the type of sub-shapes to be returned (see + ShapeType()). Can have the values FACE, + EDGE and VERTEX only. + theCondition the condition type (see GEOM::comparison_condition). + theTolerance the tolerance filter. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + The list of shapes that satisfy the conditions. + """ + # Example: see GEOM_TestAll.py + ListObj = self.ShapesOp.GetSubShapesWithTolerance(theShape, EnumToLong(theShapeType), + theCondition, theTolerance) + RaiseIfFailed("GetSubShapesWithTolerance", self.ShapesOp) + self._autoPublish(ListObj, theName, "SubShapeWithTolerance") + return ListObj + ## Check if the object is a sub-object of another GEOM object. # @param aSubObject Checked sub-object (or its parent object, in case if # \a theSubObjectIndex is non-zero). diff --git a/src/RepairGUI/CMakeLists.txt b/src/RepairGUI/CMakeLists.txt index 34310cf4c..d9ae6fa29 100755 --- a/src/RepairGUI/CMakeLists.txt +++ b/src/RepairGUI/CMakeLists.txt @@ -41,6 +41,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/DlgRef ${PROJECT_BINARY_DIR}/src/DlgRef ${PROJECT_SOURCE_DIR}/src/GEOMAlgo + ${PROJECT_SOURCE_DIR}/src/GEOMUtils ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) @@ -55,6 +56,7 @@ ADD_DEFINITIONS( # libraries to link to SET(_link_LIBRARIES GEOMBase + GEOMUtils ) # --- resources --- diff --git a/src/RepairGUI/RepairGUI.cxx b/src/RepairGUI/RepairGUI.cxx index 6c177ab85..3eadcbe21 100644 --- a/src/RepairGUI/RepairGUI.cxx +++ b/src/RepairGUI/RepairGUI.cxx @@ -98,7 +98,7 @@ bool RepairGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent ) case GEOMOp::OpRemoveExtraEdges: aDlg = new RepairGUI_RemoveExtraEdgesDlg (getGeometryGUI(), parent); break; case GEOMOp::OpFuseEdges: aDlg = new RepairGUI_FuseEdgesDlg (getGeometryGUI(), parent); break; case GEOMOp::OpUnionFaces: aDlg = new RepairGUI_UnionFacesDlg (getGeometryGUI(), parent); break; - case GEOMOp::OpInspectObj: aDlg = new RepairGUI_InspectObjectDlg (parent); break; + case GEOMOp::OpInspectObj: aDlg = new RepairGUI_InspectObjectDlg (getGeometryGUI(), parent); break; default: app->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID)); break; diff --git a/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx b/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx index e0c5ef0ba..a66f9c18e 100644 --- a/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx +++ b/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx @@ -24,6 +24,7 @@ #include #include #include +#include // GUI includes #include @@ -35,19 +36,47 @@ #include #include +#include #include #include #include // OCCT includes +#include +#include +#include +#include #include +#include +#include // Qt includes +#include +#include #include +#include #include #include #include +#include +#include +#include +#include + +// Shape type definitions (values are equal to corresponding types of TopAbs_ShapeEnum). +#define TYPE_FACE 4 +#define TYPE_EDGE 6 +#define TYPE_VERTEX 7 + +// Comparison type definitions +#define COMPARE_GT 0 +#define COMPARE_GE 1 +#define COMPARE_LT 2 +#define COMPARE_LE 3 + +// Default tolerance values +#define DEFAULT_TOLERANCE_VALUE 1.e-07 //================================================================================= // class : RepairGUI_InspectObjectDlg::TreeWidgetItem @@ -56,8 +85,20 @@ class RepairGUI_InspectObjectDlg::TreeWidgetItem : public QTreeWidgetItem { public: - TreeWidgetItem( QTreeWidget*, const QStringList&, const TopoDS_Shape&, const Handle(SALOME_InteractiveObject)&, int = Type ); - TreeWidgetItem( QTreeWidgetItem*, const QStringList&, const TopoDS_Shape&, const QString&, int = Type ); + TreeWidgetItem(QTreeWidget*, + const QStringList&, + const TopoDS_Shape&, + const Handle(SALOME_InteractiveObject)&, + double = DEFAULT_TOLERANCE_VALUE, + int = Type); + + TreeWidgetItem(QTreeWidgetItem*, + const QStringList&, + const TopoDS_Shape&, + const QString&, + double = DEFAULT_TOLERANCE_VALUE, + int = Type); + ~TreeWidgetItem(); bool isVisible(); @@ -66,27 +107,43 @@ public: TopoDS_Shape getShape() const; Handle(SALOME_InteractiveObject) getIO() const; + double getTolerance() const; + void setTolerance(double theTolerance); + private: bool myIsVisible; TopoDS_Shape myShape; Handle(SALOME_InteractiveObject) myIO; + double myTolerance; }; -RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem( QTreeWidget* view, const QStringList &strings, const TopoDS_Shape& shape, - const Handle(SALOME_InteractiveObject)& io, int type ) +RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem + (QTreeWidget *view, + const QStringList &strings, + const TopoDS_Shape &shape, + const Handle(SALOME_InteractiveObject) &io, + double theTolerance, + int type) : QTreeWidgetItem( view, strings, type ), myIsVisible( false ), myShape( shape ), - myIO( io ) + myIO( io ), + myTolerance (theTolerance) { } -RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem( QTreeWidgetItem* parent, const QStringList &strings, - const TopoDS_Shape& shape, const QString& entry, int type ) +RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem + (QTreeWidgetItem *parent, + const QStringList &strings, + const TopoDS_Shape &shape, + const QString &entry, + double theTolerance, + int type) : QTreeWidgetItem( parent, strings, type ), myIsVisible( false ), - myShape( shape ) + myShape( shape ), + myTolerance (theTolerance) { myIO = new SALOME_InteractiveObject( entry.toAscii(), "GEOM", "TEMP_IO" ); setFlags( flags() | Qt::ItemIsEditable ); @@ -117,6 +174,16 @@ Handle(SALOME_InteractiveObject) RepairGUI_InspectObjectDlg::TreeWidgetItem::get return myIO; } +double RepairGUI_InspectObjectDlg::TreeWidgetItem::getTolerance() const +{ + return myTolerance; +} + +void RepairGUI_InspectObjectDlg::TreeWidgetItem::setTolerance(double theTolerance) +{ + myTolerance = theTolerance; +} + //================================================================================= // class : RepairGUI_InspectObjectDlg::Delegate // purpose : class for "Inspect Object" tree item editing @@ -169,120 +236,156 @@ QWidget* RepairGUI_InspectObjectDlg::Delegate::createEditor( QWidget* parent, // class : RepairGUI_InspectObjectDlg() // purpose : Constructs a RepairGUI_InspectObjectDlg which is a child of 'parent'. //================================================================================= -RepairGUI_InspectObjectDlg::RepairGUI_InspectObjectDlg( SUIT_Desktop* parent ) -: GEOMBase_Helper( parent ), - QDialog( parent ), - myTransparency( 0.0 ), - myIsSelectAll( false ) +RepairGUI_InspectObjectDlg::RepairGUI_InspectObjectDlg(GeometryGUI *theGeomGUI, SUIT_Desktop* parent ) +: GEOMBase_Helper (parent), + QDialog (parent), + myGeomGUI (theGeomGUI), + myTreeObjects (0), + myFilteredTreeObjects (0), + myCurrentTreeObjects (0), + myEditMainShape (0), + myTolFilterGrp (0), + myShapeTypeBtnGrp (0), + myComparisonCompo (0), + myMinTolValLabel (0), + myMaxTolValLabel (0), + myTolEdit (0), + myTreesLayout (0), + myTransparency (0.0), + myIsSelectAll (false), + myMaxTol (-1.), + myMinTol (-1.) { - QIcon iconSelect( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); - myVisible = QIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) ); - myInvisible = QIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) ); + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + QIcon iconSelect( resMgr->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); + myVisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) ); + myInvisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) ); + + QPixmap anImageVtx(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_VERTEX"))); + QPixmap anImageEdge(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_EDGE"))); + QPixmap anImageFace(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_FACE"))); setWindowTitle( tr( "GEOM_INSPECT_OBJECT_TITLE" ) ); setAttribute( Qt::WA_DeleteOnClose ); - myApp = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() ); - myViewWindow = myApp->desktop()->activeWindow(); + myViewWindow = myGeomGUI->getApp()->desktop()->activeWindow(); QGridLayout* topLayout = new QGridLayout( this ); topLayout->setMargin( 11 ); topLayout->setSpacing( 6 ); /********************** Inspected Object **********************/ - QHBoxLayout* mainShapeLayout = new QHBoxLayout(); + QHBoxLayout* mainShapeLayout = new QHBoxLayout(this); - QLabel* label = new QLabel( tr( "GEOM_INSPECT_OBJECT_MAIN_SHAPE" ) ); - QPushButton* selBtn = new QPushButton(); + QLabel* label = new QLabel( tr( "GEOM_INSPECT_OBJECT_MAIN_SHAPE" ), this ); + QPushButton* selBtn = new QPushButton(this); selBtn->setIcon( iconSelect ); - myEditMainShape = new QLineEdit(); + myEditMainShape = new QLineEdit(this); myEditMainShape->setReadOnly(true); mainShapeLayout->addWidget( label ); mainShapeLayout->addWidget( selBtn ); mainShapeLayout->addWidget( myEditMainShape ); - /********************** Sub-objects tree **********************/ + /********************** Tolerance filter **********************/ - myTreeObjects = new QTreeWidget(); - myTreeObjects->setColumnCount( 2 ); - QStringList columnNames; - columnNames.append( tr( "GEOM_INSPECT_OBJECT_NAME" ) ); - columnNames.append(""); - myTreeObjects->setHeaderLabels( columnNames ); - QTreeWidgetItem* headerItem = new QTreeWidgetItem( columnNames ); - myTreeObjects->setHeaderItem( headerItem ); - myTreeObjects->header()->moveSection( 1, 0 ); - myTreeObjects->header()->setClickable( true ); - myTreeObjects->header()->setMovable( false ); - myTreeObjects->header()->setResizeMode( 1, QHeaderView::ResizeToContents ); - myTreeObjects->setSelectionMode( QAbstractItemView::ExtendedSelection ); - myTreeObjects->setEditTriggers( QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed ); - // set custom item delegate - myTreeObjects->setItemDelegate( new Delegate( myTreeObjects ) ); + myTolFilterGrp = new QGroupBox (tr("GEOM_INSPECT_TOLERANCE_FILTER"), this); + myShapeTypeBtnGrp = new QButtonGroup(myTolFilterGrp); + + // Filter on shape type + QRadioButton *aVtx = new QRadioButton(tr("GEOM_VERTEX"), myTolFilterGrp); + QRadioButton *anEdge = new QRadioButton(tr("GEOM_EDGE"), myTolFilterGrp); + QRadioButton *aFace = new QRadioButton(tr("GEOM_FACE"), myTolFilterGrp); + + aVtx->setIcon(anImageVtx); + anEdge->setIcon(anImageEdge); + aFace->setIcon(anImageFace); + myShapeTypeBtnGrp->addButton(aVtx, TYPE_VERTEX); + myShapeTypeBtnGrp->addButton(anEdge, TYPE_EDGE); + myShapeTypeBtnGrp->addButton(aFace, TYPE_FACE); + + // Filter on sub-shape tolerance + QLabel *aTolLabel = new QLabel(tr("GEOM_TOLERANCE"), myTolFilterGrp); + QLabel *aMinTolLabel = new QLabel(tr("GEOM_MIN"), myTolFilterGrp); + QLabel *aMaxTolLabel = new QLabel(tr("GEOM_MAX"), myTolFilterGrp); + QGridLayout *aFilterLayout = new QGridLayout(myTolFilterGrp); + + myMinTolValLabel = new QLabel(myTolFilterGrp); + myMaxTolValLabel = new QLabel(myTolFilterGrp); + myMinTolResetBtn = new QPushButton(tr("GEOM_INSPECT_RESET_MIN"), myTolFilterGrp); + myMaxTolResetBtn = new QPushButton(tr("GEOM_INSPECT_RESET_MAX"), myTolFilterGrp); + myComparisonCompo = new QComboBox(myTolFilterGrp); + myTolEdit = new SalomeApp_DoubleSpinBox(myTolFilterGrp); + myTolEdit->setMinimumWidth(120); + aFilterLayout->addWidget(aVtx, 0, 0); + aFilterLayout->addWidget(anEdge, 0, 1); + aFilterLayout->addWidget(aFace, 0, 2); + aFilterLayout->addWidget(aMaxTolLabel, 1, 0, Qt::AlignRight); + aFilterLayout->addWidget(aTolLabel, 2, 0); + aFilterLayout->addWidget(aMinTolLabel, 3, 0, Qt::AlignRight); + aFilterLayout->addWidget(myMaxTolValLabel, 1, 1); + aFilterLayout->addWidget(myComparisonCompo, 2, 1); + aFilterLayout->addWidget(myMinTolValLabel, 3, 1); + aFilterLayout->addWidget(myMaxTolResetBtn, 1, 2); + aFilterLayout->addWidget(myTolEdit, 2, 2); + aFilterLayout->addWidget(myMinTolResetBtn, 3, 2); + aFilterLayout->setRowMinimumHeight(0, 30); + + myTolFilterGrp->setCheckable(true); + + /********************** Sub-objects trees **********************/ + createTreeWidget(myTreeObjects); + createTreeWidget(myFilteredTreeObjects); + + myTreesLayout = new QStackedLayout(this); + myTreesLayout->addWidget(myTreeObjects); + myTreesLayout->addWidget(myFilteredTreeObjects); /********************** Buttons **********************/ - QVBoxLayout* buttonsLayout1 = new QVBoxLayout(); + QVBoxLayout* buttonsLayout1 = new QVBoxLayout(this); + + QPushButton* buttonShow = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW" ), this ); + QPushButton* buttonShowOnly = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW_ONLY" ), this ); + QPushButton* buttonHide = new QPushButton( tr( "GEOM_INSPECT_OBJECT_HIDE" ), this ); + QPushButton* buttonPublish = new QPushButton( tr( "GEOM_INSPECT_OBJECT_PUBLISH" ), this ); + QPushButton* aShowAllBtn = new QPushButton(tr("SHOW_ALL_BTN"), this); + QPushButton* aHideAllBtn = new QPushButton(tr("HIDE_ALL_BTN"), this); - QPushButton* buttonShow = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW" ) ); - QPushButton* buttonShowOnly = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW_ONLY" ) ); - QPushButton* buttonHide = new QPushButton( tr( "GEOM_INSPECT_OBJECT_HIDE" ) ); - QPushButton* buttonPublish = new QPushButton( tr( "GEOM_INSPECT_OBJECT_PUBLISH" ) ); buttonsLayout1->addWidget( buttonShow ); buttonsLayout1->addWidget( buttonShowOnly ); buttonsLayout1->addWidget( buttonHide ); - buttonsLayout1->addStretch(); + buttonsLayout1->addWidget( aShowAllBtn ); + buttonsLayout1->addWidget( aHideAllBtn ); buttonsLayout1->addWidget( buttonPublish ); buttonsLayout1->addStretch(); - QHBoxLayout* buttonsLayout2 = new QHBoxLayout(); + QHBoxLayout* buttonsLayout2 = new QHBoxLayout(this); - QPushButton* buttonClose = new QPushButton( tr( "GEOM_BUT_CLOSE" ) ); - QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ) ); + QPushButton* buttonClose = new QPushButton( tr( "GEOM_BUT_CLOSE" ), this ); + QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ), this ); buttonsLayout2->addWidget( buttonClose ); buttonsLayout2->addStretch(); buttonsLayout2->addWidget( buttonHelp ); topLayout->addLayout( mainShapeLayout, 0, 0 ); - topLayout->addWidget( myTreeObjects, 1, 0 ); - topLayout->addLayout( buttonsLayout1, 0, 1, 2, 1 ); - topLayout->addLayout( buttonsLayout2, 2, 0, 1, 2 ); - - // Signals and slots connections + topLayout->addWidget( myTolFilterGrp, 1, 0); + topLayout->addLayout( myTreesLayout, 2, 0 ); + topLayout->addLayout( buttonsLayout1, 0, 1, 3, 1 ); + topLayout->addLayout( buttonsLayout2, 3, 0, 1, 2 ); connect( selBtn, SIGNAL( clicked() ), this, SLOT( onEditMainShape() ) ); - connect( myTreeObjects, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), - this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) ); - connect( myTreeObjects, SIGNAL( itemChanged( QTreeWidgetItem*, int ) ), - this, SLOT( onItemChanged( QTreeWidgetItem*, int ) ) ); - connect( myTreeObjects, SIGNAL( itemExpanded ( QTreeWidgetItem* ) ), - this, SLOT( onItemExpanded( QTreeWidgetItem* ) ) ); - connect( myTreeObjects, SIGNAL( itemSelectionChanged() ), - this, SLOT( onItemSelectionChanged() ) ); - - connect( myTreeObjects->header(), SIGNAL( sectionClicked( int ) ), this, SLOT( onHeaderClicked( int ) ) ); - connect( buttonShow, SIGNAL( clicked() ), this, SLOT( clickOnShow() ) ); connect( buttonShowOnly, SIGNAL( clicked() ), this, SLOT( clickOnShowOnly() ) ); connect( buttonHide, SIGNAL( clicked() ), this, SLOT( clickOnHide() ) ); connect( buttonPublish, SIGNAL( clicked() ), this, SLOT( clickOnPublish() ) ); - connect( buttonClose, SIGNAL( clicked() ), this, SLOT( reject() ) ); connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( clickOnHelp() ) ); - - connect( myApp->selectionMgr(), SIGNAL( currentSelectionChanged() ), - this, SLOT( onViewSelectionChanged() ) ); - - connect( myApp->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ), - this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ) ); - - if ( myViewWindow ) - connect( myViewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ), - this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); + connect( aShowAllBtn, SIGNAL( clicked() ), this, SLOT( clickOnShowAll() ) ); + connect( aHideAllBtn, SIGNAL( clicked() ), this, SLOT( clickOnHideAll() ) ); init(); } @@ -297,59 +400,133 @@ RepairGUI_InspectObjectDlg::~RepairGUI_InspectObjectDlg() // no need to delete child widgets, Qt does it all for us } +//================================================================================= +// function : createTreeWidget() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::createTreeWidget(QTreeWidget *&theTreeObjects) +{ + theTreeObjects = new QTreeWidget(this); + theTreeObjects->setColumnCount(2); + QStringList columnNames; + columnNames.append(tr("GEOM_INSPECT_OBJECT_NAME")); + columnNames.append(""); + theTreeObjects->setHeaderLabels(columnNames); + QTreeWidgetItem* headerItem = new QTreeWidgetItem(columnNames); + + headerItem->setIcon(1, myInvisible); + theTreeObjects->setHeaderItem(headerItem); + theTreeObjects->header()->moveSection(1, 0); + theTreeObjects->header()->setClickable(true); + theTreeObjects->header()->setMovable(false); + theTreeObjects->header()->setResizeMode( 1, QHeaderView::ResizeToContents); + theTreeObjects->setSelectionMode(QAbstractItemView::ExtendedSelection); + theTreeObjects->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); + // set custom item delegate + theTreeObjects->setItemDelegate(new Delegate(theTreeObjects)); +} + //================================================================================= // function : init() // purpose : initialize dialog data //================================================================================= void RepairGUI_InspectObjectDlg::init() { - //get shape from selection - SALOME_ListIO selected; - myApp->selectionMgr()->selectedObjects(selected); + myTolFilterGrp->setChecked(false); + myComparisonCompo->addItem(">", GEOMUtils::CC_GT); + myComparisonCompo->addItem(">=", GEOMUtils::CC_GE); + myComparisonCompo->addItem("<", GEOMUtils::CC_LT); + myComparisonCompo->addItem("<=", GEOMUtils::CC_LE); - if ( selected.Extent() != 1 ) - return; + initSpinBox(myTolEdit, 0., 100., DEFAULT_TOLERANCE_VALUE, "len_tol_precision"); + myTolEdit->setValue(DEFAULT_TOLERANCE_VALUE); - if ( !myViewWindow ) { - SUIT_ViewManager* occVm = myApp->getViewManager( OCCViewer_Viewer::Type(), true ); - myViewWindow = occVm->getActiveView(); - connect( occVm, SIGNAL( deleteView( SUIT_ViewWindow* ) ), + // Signals and slots connections + initTreeWidget(myTreeObjects); + initTreeWidget(myFilteredTreeObjects); + myCurrentTreeObjects = myTreeObjects; + myMaxTolResetBtn->setEnabled(false); + myMinTolResetBtn->setEnabled(false); + + connect(myMinTolResetBtn, SIGNAL(clicked()), this, SLOT(clickOnResetToMin())); + connect(myMaxTolResetBtn, SIGNAL(clicked()), this, SLOT(clickOnResetToMax())); + connect(myShapeTypeBtnGrp, SIGNAL(buttonClicked(int)), this, SLOT(onInitFilteredData())); + connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); + connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(reject())); + + connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ), + this, SLOT( onViewSelectionChanged() ) ); + + connect( myGeomGUI->getApp()->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ), + this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ) ); + + // Connect signals and slots for filter group box elements. + connect(myTolFilterGrp, SIGNAL(toggled(bool)), + this, SLOT(onFilterToggled(bool))); + connect(myComparisonCompo, SIGNAL(currentIndexChanged(int)), + this, SLOT(onFilterData())); + connect(myTolEdit, SIGNAL(valueChanged(double)), + this, SLOT(onFilterData())); + + if ( myViewWindow ) + connect( myViewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ), this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); - } - TopoDS_Shape aShape = GEOMBase::GetTopoFromSelection( selected ); - if ( aShape.IsNull() ) - return; + // Initialize the dialog with current selection. + onViewSelectionChanged(); +} - Handle(SALOME_InteractiveObject) anIO = selected.First(); - GEOM::GEOM_Object_var anObject = GEOMBase::ConvertIOinGEOMObject( anIO ); - QString aName = anObject->GetName(); - CORBA::String_var anEntry = anObject->GetStudyEntry(); +//================================================================================= +// function : initSpinBox() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::initSpinBox(SalomeApp_DoubleSpinBox* spinBox, + double min, double max, + double step, const char* quantity) +{ + // Obtain precision from preferences + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + int aPrecision = resMgr->integerValue( "Geometry", quantity, 6 ); + + spinBox->setPrecision( aPrecision ); + spinBox->setDecimals( qAbs( aPrecision ) ); // it's necessary to set decimals before the range setting, + // by default Qt rounds boundaries to 2 decimals at setRange + spinBox->setRange( min, max ); + spinBox->setSingleStep( step ); + + // Add a hint for the user saying how to tune precision + QString userPropName = QObject::tr( QString( "GEOM_PREF_%1" ).arg( quantity ).toLatin1().constData() ); + spinBox->setProperty( "validity_tune_hint", + QVariant( QObject::tr( "GEOM_PRECISION_HINT" ).arg( userPropName ) ) ); +} - myEditMainShape->setText( aName ); - myEditMainShape->setEnabled( false ); +//================================================================================= +// function : initTreeWidget() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::initTreeWidget(QTreeWidget *theTreeObjects) +{ + connect(theTreeObjects, SIGNAL(itemClicked (QTreeWidgetItem *, int)), + this, SLOT(onItemClicked(QTreeWidgetItem *, int))); + connect(theTreeObjects, SIGNAL(itemChanged (QTreeWidgetItem *, int)), + this, SLOT(onItemChanged(QTreeWidgetItem *, int))); + connect(theTreeObjects, SIGNAL(itemExpanded (QTreeWidgetItem *)), + this, SLOT(onItemExpanded(QTreeWidgetItem *))); + connect(theTreeObjects, SIGNAL(itemSelectionChanged()), + this, SLOT(onItemSelectionChanged())); - // remember initial transparency value - SalomeApp_Study* aStudy = dynamic_cast( myApp->activeStudy() ); - QVariant v = aStudy->getObjectProperty( myViewWindow->getViewManager()->getGlobalId(), - QString( anEntry.in() ), - GEOM::propertyName( GEOM::Transparency ), myTransparency ); - if ( v.canConvert( QVariant::Double ) ) - myTransparency = v.toDouble(); + connect(theTreeObjects->header(), SIGNAL(sectionClicked(int)), + this, SLOT(onHeaderClicked(int))); +} - TreeWidgetItem* anItem = new TreeWidgetItem( myTreeObjects, QStringList() << aName, aShape, anIO ); - if ( getDisplayer()->IsDisplayed( anEntry.in() ) ) - anItem->setVisible( true, myVisible ); - else - anItem->setVisible( false, myInvisible ); - - setMainObjectTransparency( 0.5 ); - - // add sub-objects in the tree - addSubObjects( anItem ); - - // check icon for tree header - checkVisibleIcon(); +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::enterEvent (QEvent*) +{ + if (!myTolFilterGrp->isEnabled()) + ActivateThisDialog(); } //================================================================================= @@ -359,20 +536,22 @@ void RepairGUI_InspectObjectDlg::init() void RepairGUI_InspectObjectDlg::checkVisibleIcon() { bool isInvisible = false; - QTreeWidgetItemIterator it( myTreeObjects ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); - if ( !anItem->isVisible() ) + if ( !anItem->isHidden() && !anItem->isVisible() ) { isInvisible = true; + break; + } ++it; } if ( isInvisible ) { - myTreeObjects->headerItem()->setIcon( 1, myInvisible ); + myCurrentTreeObjects->headerItem()->setIcon( 1, myInvisible ); myIsSelectAll = false; } else { - myTreeObjects->headerItem()->setIcon( 1, myVisible ); + myCurrentTreeObjects->headerItem()->setIcon( 1, myVisible ); myIsSelectAll = true; } } @@ -381,20 +560,205 @@ void RepairGUI_InspectObjectDlg::checkVisibleIcon() // function : addSubObjects() // purpose : add sub-objects to parent object in the tree //================================================================================= -void RepairGUI_InspectObjectDlg::addSubObjects( TreeWidgetItem* theParentItem ) +void RepairGUI_InspectObjectDlg::addSubObjects + (TreeWidgetItem *theParentItem, + const TopTools_IndexedMapOfShape &theIndices) { TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); TopoDS_Iterator it( theParentItem->getShape() ); for ( ; it.More(); it.Next() ) { TopoDS_Shape aSubShape = it.Value(); - int anIndex = GEOMBase::GetIndex( aSubShape, aMainItem->getShape() ); + int anIndex = theIndices.FindIndex(aSubShape); QString anEntry = QString( "TEMP_" ) + aMainItem->getIO()->getEntry() + QString("_%1").arg( anIndex ); TreeWidgetItem* anItem = new TreeWidgetItem( theParentItem, QStringList(), aSubShape, anEntry); anItem->setVisible( false, myInvisible ); - addSubObjects( anItem ); + addSubObjects(anItem, theIndices); } } +//================================================================================= +// function : onInitFilteredData() +// purpose : add sub-objects to parent object in the filtered tree +//================================================================================= +void RepairGUI_InspectObjectDlg::onInitFilteredData() +{ + TreeWidgetItem *aMainItem = + dynamic_cast(myFilteredTreeObjects->topLevelItem(0)); + + if (!aMainItem) { + return; + } + + // Remove the children. + SALOME_ListIO aListOfIO; + QTreeWidgetItemIterator it(aMainItem); + + while (*it) { + TreeWidgetItem* anItem = dynamic_cast(*it); + if (aMainItem != anItem && (anItem->flags() & Qt::ItemIsSelectable) && + anItem->isVisible() && !anItem->isHidden()) { + aListOfIO.Append(anItem->getIO()); + } + + ++it; + } + + myFilteredTreeObjects->clearSelection(); + myFilteredTreeObjects->headerItem()->setIcon(1, myInvisible); + getDisplayer()->Erase(aListOfIO); + getDisplayer()->UpdateViewer(); + + // Delete child items. + QList aListItems = aMainItem->takeChildren(); + + foreach (QTreeWidgetItem *anItem, aListItems) { + delete anItem; + } + + // Initialize the tree with a new list. + TopoDS_Shape aShape = aMainItem->getShape(); + TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); + + myShapeTypeBtnGrp->button(TYPE_FACE)->setVisible(aShapeType < TYPE_FACE); + myShapeTypeBtnGrp->button(TYPE_EDGE)->setVisible(aShapeType < TYPE_EDGE); + myShapeTypeBtnGrp->button(TYPE_VERTEX)->setVisible(aShapeType < TYPE_VERTEX); + + int anId = myShapeTypeBtnGrp->checkedId(); + + myMaxTol = -RealLast(); + myMinTol = RealLast(); + + if (anId != -1 && myShapeTypeBtnGrp->checkedButton()->isVisible()) { + // Get sub-shapes + TopTools_MapOfShape aMapFence; + TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)anId); + TopTools_IndexedMapOfShape anIndices; + + TopExp::MapShapes(aShape, anIndices); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aSubShape = anExp.Current(); + + if (aMapFence.Add(aSubShape)) { + // Compute tolerance + Standard_Real aTolerance = -1.; + + switch (aSubShape.ShapeType()) { + case TYPE_FACE: + aTolerance = BRep_Tool::Tolerance(TopoDS::Face(aSubShape)); + break; + case TYPE_EDGE: + aTolerance = BRep_Tool::Tolerance(TopoDS::Edge(aSubShape)); + break; + case TYPE_VERTEX: + aTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(aSubShape)); + break; + default: + break; + } + + if (aTolerance < 0.) { + continue; + } + + if (aTolerance > myMaxTol) { + myMaxTol = aTolerance; + } + + if (aTolerance < myMinTol) { + myMinTol = aTolerance; + } + + int anIndex = anIndices.FindIndex(aSubShape); + QString anEntry = QString( "TEMP_" ) + + aMainItem->getIO()->getEntry() + + QString::number(anIndex); + TreeWidgetItem* anItem = + new TreeWidgetItem(aMainItem, QStringList(), + aSubShape, anEntry, aTolerance); + anItem->setVisible( false, myInvisible ); + } + } + } + + // Compose names of sub-items if the main item is expanded. + if (aMainItem->isExpanded()) { + onItemExpanded(aMainItem); + } + + myMaxTolResetBtn->setEnabled(myMaxTol >= myMinTol); + myMinTolResetBtn->setEnabled(myMaxTol >= myMinTol); + + if (myMaxTol < myMinTol) { + myMinTol = DEFAULT_TOLERANCE_VALUE; + myMaxTol = DEFAULT_TOLERANCE_VALUE; + myMinTolValLabel->setText(QString::number(DEFAULT_TOLERANCE_VALUE)); + myMaxTolValLabel->setText(QString::number(DEFAULT_TOLERANCE_VALUE)); + myTolEdit->setValue(DEFAULT_TOLERANCE_VALUE); + } else { + myMinTolValLabel->setText(QString::number(myMinTol)); + myMaxTolValLabel->setText(QString::number(myMaxTol)); + + if (GEOMUtils::CompareToleranceValues(myMinTol, myTolEdit->value()) == 1) { + clickOnResetToMin(); + } else if (GEOMUtils::CompareToleranceValues + (myMaxTol, myTolEdit->value()) == -1) { + clickOnResetToMax(); + } else { + onFilterData(); + } + } +} + +//================================================================================= +// function : onFilterData() +// purpose : filter objects in the filtered tree +//================================================================================= +void RepairGUI_InspectObjectDlg::onFilterData() +{ + TreeWidgetItem *aMainItem = + dynamic_cast(myFilteredTreeObjects->topLevelItem(0)); + + if (!aMainItem) { + return; + } + + SALOME_ListIO aListOfIOToHide; + QTreeWidgetItemIterator anIt(aMainItem); + const int aCompValue = + myComparisonCompo->itemData(myComparisonCompo->currentIndex()).toInt(); + const double aTolValue = myTolEdit->value(); + + while (*anIt) { + TreeWidgetItem* anItem = dynamic_cast(*anIt); + + if (aMainItem != anItem) { + const bool isToFilter = !GEOMUtils::IsFitCondition + ((GEOMUtils::ComparisonCondition) aCompValue, + anItem->getTolerance(), aTolValue); + + if (isToFilter && !anItem->isHidden()) { + if (anItem->isVisible()) { + aListOfIOToHide.Append(anItem->getIO()); + } + + anItem->setVisible(false, myInvisible); + } + + anItem->setHidden(isToFilter); + } + + ++anIt; + } + + if (!aListOfIOToHide.IsEmpty()) { + getDisplayer()->Erase(aListOfIOToHide); + getDisplayer()->UpdateViewer(); + } + + checkVisibleIcon(); +} + //================================================================================= // function : displayItem() // purpose : display sub-object of inspected object according its tree item @@ -402,7 +766,7 @@ void RepairGUI_InspectObjectDlg::addSubObjects( TreeWidgetItem* theParentItem ) void RepairGUI_InspectObjectDlg::displayItem( TreeWidgetItem* theItem ) { GEOM_Displayer* aDisplayer = getDisplayer(); - if ( theItem == myTreeObjects->topLevelItem(0) ) { + if ( theItem == myCurrentTreeObjects->topLevelItem(0) ) { aDisplayer->UnsetColor(); aDisplayer->UnsetWidth(); } @@ -423,7 +787,7 @@ void RepairGUI_InspectObjectDlg::displayItem( TreeWidgetItem* theItem ) //================================================================================= void RepairGUI_InspectObjectDlg::setItemDisplayStatus( TreeWidgetItem* theItem, bool theIsVisible ) { - QTreeWidgetItemIterator it( myTreeObjects ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while (*it) { TreeWidgetItem* anItem = dynamic_cast(*it); if ( anItem->getShape().IsSame( theItem->getShape() ) ) @@ -440,9 +804,14 @@ void RepairGUI_InspectObjectDlg::setMainObjectTransparency( double theTransparen { SUIT_ViewManager* aViewMan = myViewWindow->getViewManager(); SALOME_View* aView = dynamic_cast( aViewMan->getViewModel() ); - SalomeApp_Study* aStudy = dynamic_cast( myApp->activeStudy() ); + SalomeApp_Study* aStudy = dynamic_cast( myGeomGUI->getApp()->activeStudy() ); + + TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); + + if (!aMainItem) { + return; + } - TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); aStudy->setObjectProperty( myViewWindow->getViewManager()->getGlobalId(), QString( aMainItem->getIO()->getEntry() ), GEOM::propertyName( GEOM::Transparency ), theTransparency ); @@ -468,8 +837,8 @@ void RepairGUI_InspectObjectDlg::restoreParam() setMainObjectTransparency( myTransparency ); // erase sub-shapes - TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); - QTreeWidgetItemIterator it( myTreeObjects ); + TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while (*it) { if ( *it != aMainItem ) { TreeWidgetItem* anItem = dynamic_cast(*it); @@ -496,6 +865,7 @@ void RepairGUI_InspectObjectDlg::onEditMainShape() myEditMainShape->setText(""); myEditMainShape->setFocus(); myTreeObjects->clear(); + myFilteredTreeObjects->clear(); } //================================================================================= @@ -533,7 +903,7 @@ void RepairGUI_InspectObjectDlg::onItemChanged( QTreeWidgetItem* theItem, int th return; // rename the same items in the tree - QTreeWidgetItemIterator it( myTreeObjects ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); if ( anItem->getShape().IsSame( dynamic_cast( theItem )->getShape() ) ) @@ -548,7 +918,7 @@ void RepairGUI_InspectObjectDlg::onItemChanged( QTreeWidgetItem* theItem, int th //================================================================================= void RepairGUI_InspectObjectDlg::onItemExpanded( QTreeWidgetItem* theItem ) { - TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); + TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); GEOM::GEOM_Object_var aMainObject = GEOMBase::ConvertIOinGEOMObject( aMainItem->getIO() ); for ( int i = 0; i < theItem->childCount(); i++ ) { @@ -573,13 +943,13 @@ void RepairGUI_InspectObjectDlg::onItemSelectionChanged() if ( !myViewWindow ) return; - QList listItem = myTreeObjects->selectedItems(); + QList listItem = myCurrentTreeObjects->selectedItems(); SALOME_ListIO aSelected; for ( int i = 0; i < listItem.size(); i++ ) { TreeWidgetItem* anItem = dynamic_cast( listItem.at(i) ); aSelected.Append( anItem->getIO() ); } - myApp->selectionMgr()->setSelectedObjects( aSelected ); + myGeomGUI->getApp()->selectionMgr()->setSelectedObjects( aSelected ); } //================================================================================= @@ -595,12 +965,13 @@ void RepairGUI_InspectObjectDlg::onHeaderClicked( int theColumn ) if ( myIsSelectAll ) { myIsSelectAll = false; - myTreeObjects->headerItem()->setIcon( 1, myInvisible ); + myCurrentTreeObjects->headerItem()->setIcon( 1, myInvisible ); SALOME_ListIO aListOfIO; - QTreeWidgetItemIterator it( myTreeObjects ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); - if ( ( anItem->flags() & Qt::ItemIsSelectable ) && anItem->isVisible() ) { + if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) && + anItem->isVisible() ) { aListOfIO.Append( anItem->getIO() ); anItem->setVisible( false, myInvisible ); } @@ -610,11 +981,12 @@ void RepairGUI_InspectObjectDlg::onHeaderClicked( int theColumn ) } else { myIsSelectAll = true; - myTreeObjects->headerItem()->setIcon( 1, myVisible ); - QTreeWidgetItemIterator it( myTreeObjects ); + myCurrentTreeObjects->headerItem()->setIcon( 1, myVisible ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); - if ( ( anItem->flags() & Qt::ItemIsSelectable ) && !anItem->isVisible() ) { + if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) && + !anItem->isVisible() ) { displayItem( anItem ); anItem->setVisible( true, myVisible ); } @@ -631,8 +1003,68 @@ void RepairGUI_InspectObjectDlg::onHeaderClicked( int theColumn ) //================================================================================= void RepairGUI_InspectObjectDlg::onViewSelectionChanged() { - if ( myEditMainShape->isEnabled() ) - init(); + if (!myEditMainShape->isEnabled()) + return; + + //get shape from selection + SALOME_ListIO selected; + myGeomGUI->getApp()->selectionMgr()->selectedObjects(selected); + + if ( selected.Extent() != 1 ) + return; + + if ( !myViewWindow ) { + SUIT_ViewManager* occVm = myGeomGUI->getApp()->getViewManager( OCCViewer_Viewer::Type(), true ); + myViewWindow = occVm->getActiveView(); + connect( occVm, SIGNAL( deleteView( SUIT_ViewWindow* ) ), + this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); + } + + TopoDS_Shape aShape = GEOMBase::GetTopoFromSelection( selected ); + if ( aShape.IsNull() ) + return; + + Handle(SALOME_InteractiveObject) anIO = selected.First(); + GEOM::GEOM_Object_var anObject = GEOMBase::ConvertIOinGEOMObject( anIO ); + QString aName = anObject->GetName(); + CORBA::String_var anEntry = anObject->GetStudyEntry(); + + myEditMainShape->setText( aName ); + myEditMainShape->setEnabled( false ); + + // remember initial transparency value + SalomeApp_Study* aStudy = dynamic_cast( myGeomGUI->getApp()->activeStudy() ); + QVariant v = aStudy->getObjectProperty( myViewWindow->getViewManager()->getGlobalId(), + QString( anEntry.in() ), + GEOM::propertyName( GEOM::Transparency ), myTransparency ); + if ( v.canConvert( QVariant::Double ) ) + myTransparency = v.toDouble(); + + TreeWidgetItem* anItem = new TreeWidgetItem + (myTreeObjects, QStringList() << aName, aShape, anIO); + TreeWidgetItem* anItemFiltered = new TreeWidgetItem + (myFilteredTreeObjects, QStringList() << aName, aShape, anIO); + + if ( getDisplayer()->IsDisplayed( anEntry.in() ) ) { + anItem->setVisible( true, myVisible ); + anItemFiltered->setVisible( true, myVisible ); + } else { + anItem->setVisible( false, myInvisible ); + anItemFiltered->setVisible( false, myInvisible ); + } + + setMainObjectTransparency( 0.5 ); + + // add sub-objects in the tree + TopTools_IndexedMapOfShape anIndices; + + TopExp::MapShapes(aShape, anIndices); + addSubObjects(anItem, anIndices); + onInitFilteredData(); + updateViewer(false); + + // check icon for tree header + checkVisibleIcon(); } //================================================================================= @@ -654,9 +1086,9 @@ void RepairGUI_InspectObjectDlg::onWindowActivated( SUIT_ViewWindow* theViewWind } myViewWindow = theViewWindow; - if ( myTreeObjects->topLevelItemCount() > 0 ) { + if ( myCurrentTreeObjects->topLevelItemCount() > 0 ) { setMainObjectTransparency( 0.5 ); - TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); + TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); if ( getDisplayer()->IsDisplayed( aMainItem->getIO()->getEntry() ) ) aMainItem->setVisible( true, myVisible ); else @@ -671,7 +1103,7 @@ void RepairGUI_InspectObjectDlg::onWindowActivated( SUIT_ViewWindow* theViewWind //================================================================================= void RepairGUI_InspectObjectDlg::onCloseView( SUIT_ViewWindow* ) { - if ( myApp->desktop()->windows().size() == 0 ) { + if ( myGeomGUI->getApp()->desktop()->windows().size() == 0 ) { restoreParam(); myViewWindow = 0; } @@ -686,7 +1118,7 @@ void RepairGUI_InspectObjectDlg::clickOnShow() if ( !myViewWindow ) return; - QList listItem = myTreeObjects->selectedItems(); + QList listItem = myCurrentTreeObjects->selectedItems(); for ( int i = 0; i < listItem.size(); i++ ) { TreeWidgetItem* anItem = dynamic_cast( listItem.at(i) ); if ( !anItem->isVisible() ) { @@ -708,10 +1140,11 @@ void RepairGUI_InspectObjectDlg::clickOnShowOnly() return; SALOME_ListIO aListOfIO; - QTreeWidgetItemIterator it( myTreeObjects ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); - if ( ( anItem->flags() & Qt::ItemIsSelectable ) && anItem->isVisible() ) { + if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) && + anItem->isVisible() ) { aListOfIO.Append( anItem->getIO() ); anItem->setVisible( false, myInvisible ); } @@ -731,7 +1164,7 @@ void RepairGUI_InspectObjectDlg::clickOnHide() if ( !myViewWindow ) return; - QList listItem = myTreeObjects->selectedItems(); + QList listItem = myCurrentTreeObjects->selectedItems(); for ( int i = 0; i < listItem.size(); i++ ) { TreeWidgetItem* anItem = dynamic_cast( listItem.at(i) ); if ( anItem->isVisible() ) { @@ -749,14 +1182,19 @@ void RepairGUI_InspectObjectDlg::clickOnHide() //================================================================================= void RepairGUI_InspectObjectDlg::clickOnPublish() { - _PTR(Study) studyDS = dynamic_cast( myApp->activeStudy() )->studyDS(); + _PTR(Study) studyDS = dynamic_cast( myGeomGUI->getApp()->activeStudy() )->studyDS(); // find main object - TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); + TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); + + if (!aMainItem) { + return; + } + GEOM::GEOM_Object_var aMainObject = GEOMBase::ConvertIOinGEOMObject( aMainItem->getIO() ); // find unique indices of selected objects - QList selectedItems = myTreeObjects->selectedItems(); + QList selectedItems = myCurrentTreeObjects->selectedItems(); QMap< int, QString > anIndices; GEOM::ListOfLong_var anArray = new GEOM::ListOfLong; anArray->length( selectedItems.size() ); @@ -790,5 +1228,139 @@ void RepairGUI_InspectObjectDlg::clickOnPublish() //================================================================================= void RepairGUI_InspectObjectDlg::clickOnHelp() { - myApp->onHelpContextModule( "GEOM", "inspect_object_operation_page.html" ); + myGeomGUI->getApp()->onHelpContextModule( "GEOM", "inspect_object_operation_page.html" ); +} + +//================================================================================= +// function : clickOnResetToMin() +// purpose : called when Reset button was clicked to reset tolerance filter to minimal value. +//================================================================================= +void RepairGUI_InspectObjectDlg::clickOnResetToMin() +{ + if (myMinTol >= myTolEdit->minimum() && myMinTol <= myTolEdit->maximum()) { + myTolEdit->setValue(myMinTol); + } +} + +//================================================================================= +// function : clickOnResetToMax() +// purpose : called when Reset button was clicked to reset tolerance filter to maximal value. +//================================================================================= +void RepairGUI_InspectObjectDlg::clickOnResetToMax() +{ + if (myMaxTol >= myTolEdit->minimum() && myMaxTol <= myTolEdit->maximum()) { + myTolEdit->setValue(myMaxTol); + } +} + +//================================================================================= +// function : clickOnShowAll() +// purpose : called when Help button was clicked to show all shapes +//================================================================================= +void RepairGUI_InspectObjectDlg::clickOnShowAll() +{ + myIsSelectAll = false; + onHeaderClicked(1); +} + +//================================================================================= +// function : clickOnHideAll() +// purpose : called when Help button was clicked to hide all shapes +//================================================================================= +void RepairGUI_InspectObjectDlg::clickOnHideAll() +{ + myIsSelectAll = true; + onHeaderClicked(1); +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::DeactivateActiveDialog() +{ + setEnabled(false); + disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); + myGeomGUI->SetActiveDialogBox(0); + globalSelection(); + erasePreview(); +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::ActivateThisDialog() +{ + /* Emit a signal to deactivate the active dialog */ + myGeomGUI->EmitSignalDeactivateDialog(); + setEnabled(true); + myGeomGUI->SetActiveDialogBox( (QDialog*)this ); + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(onViewSelectionChanged())); + + updateViewer(false); +} + +//================================================================================= +// function : onFilterToggled() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::onFilterToggled(bool isOn) +{ + if (isOn) { + myCurrentTreeObjects = myFilteredTreeObjects; + myTreesLayout->setCurrentIndex(1); + } else { + myCurrentTreeObjects = myTreeObjects; + myTreesLayout->setCurrentIndex(0); + } + + updateViewer(true); +} + +//================================================================================= +// function : updateViewer() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::updateViewer(const bool theIsHideOtherTree) +{ + GEOM_Displayer *aDisplayer = getDisplayer(); + + if (theIsHideOtherTree) { + QTreeWidget *aTreeToHide = myCurrentTreeObjects == myTreeObjects ? + myFilteredTreeObjects: myTreeObjects; + + // Hide the objects of disappeared tree, do not switch off flags. + SALOME_ListIO aListOfIO; + QTreeWidgetItemIterator it(aTreeToHide); + + while (*it) { + TreeWidgetItem* anItem = dynamic_cast(*it); + if ((anItem->flags() & Qt::ItemIsSelectable) && + anItem->isVisible() && !anItem->isHidden()) { + aListOfIO.Append(anItem->getIO()); + } + + ++it; + } + + aDisplayer->Erase(aListOfIO); + } + + // Show the objects that are marked as shown in the appeared tree. + QTreeWidgetItemIterator it2(myCurrentTreeObjects); + + while (*it2) { + TreeWidgetItem* anItem = dynamic_cast(*it2); + if ((anItem->flags() & Qt::ItemIsSelectable) && + anItem->isVisible() && !anItem->isHidden()) { + displayItem(anItem); + } + + ++it2; + } + + aDisplayer->UpdateViewer(); } diff --git a/src/RepairGUI/RepairGUI_InspectObjectDlg.h b/src/RepairGUI/RepairGUI_InspectObjectDlg.h index d696ac904..d8ffff0d4 100644 --- a/src/RepairGUI/RepairGUI_InspectObjectDlg.h +++ b/src/RepairGUI/RepairGUI_InspectObjectDlg.h @@ -25,10 +25,23 @@ // Qt includes #include -#include -#include -#include #include +#include + +class GeometryGUI; +class SalomeApp_DoubleSpinBox; + +class QButtonGroup; +class QComboBox; +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QStackedLayout; +class QTreeWidget; +class QTreeWidgetItem; + +class TopTools_IndexedMapOfShape; class RepairGUI_InspectObjectDlg : public QDialog, public GEOMBase_Helper { @@ -38,7 +51,7 @@ class RepairGUI_InspectObjectDlg : public QDialog, public GEOMBase_Helper class Delegate; public: - RepairGUI_InspectObjectDlg( SUIT_Desktop* ); + RepairGUI_InspectObjectDlg(GeometryGUI*, SUIT_Desktop* ); ~RepairGUI_InspectObjectDlg(); private slots: @@ -60,25 +73,54 @@ private slots: void clickOnHide(); void clickOnPublish(); void clickOnHelp(); + void clickOnResetToMin(); + void clickOnResetToMax(); + void clickOnShowAll(); + void clickOnHideAll(); + void DeactivateActiveDialog(); + void ActivateThisDialog(); + void onFilterToggled(bool); + void onInitFilteredData(); + void onFilterData(); private: + void createTreeWidget(QTreeWidget *&theTreeObjects); void init(); + void initSpinBox(SalomeApp_DoubleSpinBox* spinBox, + double min, double max, + double step, const char* quantity); + void initTreeWidget(QTreeWidget *theTopLevelItem); + void enterEvent( QEvent* ); void checkVisibleIcon(); - void addSubObjects( TreeWidgetItem* ); + void addSubObjects( TreeWidgetItem*, const TopTools_IndexedMapOfShape &); + void displayItem( TreeWidgetItem* ); void setItemDisplayStatus( TreeWidgetItem* theItem, bool theIsVisible ); void setMainObjectTransparency( double ); void restoreParam(); + void updateViewer(const bool theIsHideOtherTree); - SalomeApp_Application* myApp; QPointer myViewWindow; + GeometryGUI* myGeomGUI; QIcon myVisible; QIcon myInvisible; - QTreeWidget* myTreeObjects; - QLineEdit* myEditMainShape; - + QTreeWidget *myTreeObjects; + QTreeWidget *myFilteredTreeObjects; + QTreeWidget *myCurrentTreeObjects; + QLineEdit *myEditMainShape; + QGroupBox *myTolFilterGrp; + QButtonGroup *myShapeTypeBtnGrp; + QComboBox *myComparisonCompo; + SalomeApp_DoubleSpinBox *myTolEdit; + QLabel *myMinTolValLabel; + QLabel *myMaxTolValLabel; + QStackedLayout *myTreesLayout; + QPushButton *myMinTolResetBtn; + QPushButton *myMaxTolResetBtn; + double myMaxTol; + double myMinTol; bool myIsSelectAll; double myTransparency; From 072d2d2cd9276a6cd38c4450292d5f7667ca6dd8 Mon Sep 17 00:00:00 2001 From: mkr Date: Mon, 17 Aug 2015 11:03:48 +0300 Subject: [PATCH 17/63] Run tests on Windows platform. --- doc/salome/examples/testme.py | 12 +++++++++++- src/XAO/tests/TestUtils.hxx | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/salome/examples/testme.py b/doc/salome/examples/testme.py index 0f16a4288..3e0e49698 100755 --- a/doc/salome/examples/testme.py +++ b/doc/salome/examples/testme.py @@ -24,11 +24,21 @@ import unittest, sys, os class SalomeSession(object): def __init__(self, script): import runSalome - sys.argv = ["runSalome.py"] + run_script = "runSalome.py" + if sys.platform == 'win32': + module_dir = os.getenv("KERNEL_ROOT_DIR") + if module_dir: run_script = os.path.join(module_dir, "bin", "salome", run_script) + pass + sys.argv = [run_script] sys.argv += ["--terminal"] sys.argv += ["--modules=GEOM"] sys.argv += ["%s" % script] + if sys.platform == 'win32': + main_module_path = sys.modules['__main__'].__file__ + sys.modules['__main__'].__file__ = '' clt, d = runSalome.main() + if sys.platform == 'win32': + sys.modules['__main__'].__file__ = main_module_path return def __del__(self): diff --git a/src/XAO/tests/TestUtils.hxx b/src/XAO/tests/TestUtils.hxx index a541371bf..1661cc0bb 100644 --- a/src/XAO/tests/TestUtils.hxx +++ b/src/XAO/tests/TestUtils.hxx @@ -40,7 +40,7 @@ namespace XAO { std::ifstream rstr; int length; - rstr.open(filePath.c_str()); + rstr.open(filePath.c_str(), std::ios_base::binary); rstr.seekg(0, rstr.end); // go to the end length = rstr.tellg(); // report location (this is the length) rstr.seekg(0, rstr.beg); // go back to the beginning From 449aed5c8e6cb17a3099613621906e3b838bffab Mon Sep 17 00:00:00 2001 From: mpa Date: Fri, 6 Nov 2015 13:15:49 +0300 Subject: [PATCH 18/63] 0052938: Visibility of object is wrong when closing "Create group" dilaog --- src/GroupGUI/GroupGUI_GroupDlg.cxx | 10 ++++++---- src/GroupGUI/GroupGUI_GroupDlg.h | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/GroupGUI/GroupGUI_GroupDlg.cxx b/src/GroupGUI/GroupGUI_GroupDlg.cxx index 40463f32a..5bf351f85 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.cxx +++ b/src/GroupGUI/GroupGUI_GroupDlg.cxx @@ -88,7 +88,8 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW myBusy(false), myIsShapeType(false), myIsHiddenMain(false), - myWasHiddenMain(true) + myWasHiddenMain(true), + myIsAccept(false) { SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); @@ -235,10 +236,10 @@ GroupGUI_GroupDlg::~GroupGUI_GroupDlg() GEOM_Displayer* aDisplayer = getDisplayer(); SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); bool isHideObjects = resMgr->booleanValue( "Geometry", "hide_input_object", true); - if (myWasHiddenMain) { + if (myWasHiddenMain || ( isHideObjects && myIsAccept ) ) { myIsHiddenMain = true; } - else if (!isHideObjects) { + else { aDisplayer->Display(myMainObj); myIsHiddenMain = false; } @@ -395,7 +396,8 @@ bool GroupGUI_GroupDlg::ClickOnApply() setIsDisplayResult( false ); } - if (!onAccept(myMode == CreateGroup, true, isApplyAndClose())) + myIsAccept = onAccept(myMode == CreateGroup, true, isApplyAndClose()); + if (!myIsAccept) return false; if(!isApplyAndClose()) { diff --git a/src/GroupGUI/GroupGUI_GroupDlg.h b/src/GroupGUI/GroupGUI_GroupDlg.h index 06ecae4cf..4a2385b04 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.h +++ b/src/GroupGUI/GroupGUI_GroupDlg.h @@ -115,6 +115,7 @@ private: TColStd_DataMapOfIntegerInteger myMain2InPlaceIndices; QList myGroupIdList; int myDmMode; + bool myIsAccept; QPushButton* mySelBtn; QLineEdit* myMainName; From d3b57addeba21310e2fdda7d7665d8b177129a54 Mon Sep 17 00:00:00 2001 From: ana Date: Thu, 12 Nov 2015 09:55:00 +0300 Subject: [PATCH 19/63] Win32 compatibility --- src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 5078a386a..d8e4f9fb2 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -464,7 +464,7 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations * \param theTolerance the tolerance filter. * \return the list of shapes that satisfy the conditions. */ - Handle(TColStd_HSequenceOfTransient) GetSubShapesWithTolerance + Standard_EXPORT Handle(TColStd_HSequenceOfTransient) GetSubShapesWithTolerance (const Handle(GEOM_Object) &theShape, const Standard_Integer theShapeType, const GEOMUtils::ComparisonCondition theCondition, From 937cc3a449d8fad5ef389ca8b78a2850ad24f220 Mon Sep 17 00:00:00 2001 From: mpa Date: Tue, 17 Nov 2015 14:01:00 +0300 Subject: [PATCH 20/63] INT PAL 0052942: Error of geompy.MakeCurveParametric() is printed to a terminal instead of the Python Console --- src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx index 2ee635e31..259e7061f 100644 --- a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx @@ -997,7 +997,7 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric PyObject* obj = PyRun_String(aPyScript.ToCString(), Py_file_input, main_dict, NULL); - if (obj == NULL) { + if (obj == NULL || obj == Py_None ) { SetErrorCode("Error during executing of python script !!!"); PyErr_Print(); PyGILState_Release(gstate); From 007a4cd246f7296b68ac2f2cfc308686f521cb1c Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 26 Nov 2015 15:27:30 +0300 Subject: [PATCH 21/63] Revert previous commit as it causes regression --- src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx index 259e7061f..cdf43e5e5 100644 --- a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx @@ -996,8 +996,9 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric PyObject* main_dict = PyModule_GetDict(main_mod); PyObject* obj = PyRun_String(aPyScript.ToCString(), Py_file_input, main_dict, NULL); + printf("%s\n", aPyScript.ToCString()); - if (obj == NULL || obj == Py_None ) { + if (obj == NULL) { SetErrorCode("Error during executing of python script !!!"); PyErr_Print(); PyGILState_Release(gstate); @@ -1008,7 +1009,7 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric PyObject * func = NULL; func = PyObject_GetAttrString(main_mod, "coordCalculator"); - + if (func == NULL){ SetErrorCode("Can't get function from python module !!!"); PyGILState_Release(gstate); From 0138a9d57c5ac81acf40d0c8e20765f1c2b29538 Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 1 Dec 2015 12:29:08 +0300 Subject: [PATCH 22/63] INT PAL 0052942: Error of geompy.MakeCurveParametric() is printed to a terminal instead of the Python Console - Correct fix now --- src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx | 198 ++++++++++---------- src/GEOM_SWIG/geomBuilder.py | 4 +- 2 files changed, 100 insertions(+), 102 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx index cdf43e5e5..8e3dab46b 100644 --- a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx @@ -78,105 +78,105 @@ * =========== PYTHON ============== * ==================================*/ -typedef struct { - PyObject_HEAD - int softspace; - std::string *out; +namespace +{ + typedef struct { + PyObject_HEAD + int softspace; + std::string *out; } PyStdOut; + + static void + PyStdOut_dealloc(PyStdOut *self) + { + PyObject_Del(self); + } -static void -PyStdOut_dealloc(PyStdOut *self) -{ - PyObject_Del(self); + static PyObject* + PyStdOut_write(PyStdOut* self, PyObject* args) + { + char *c; + int l; + if (!PyArg_ParseTuple(args, "t#:write", &c, &l)) + return NULL; + + *(self->out) = *(self->out) + c; + + Py_INCREF(Py_None); + return Py_None; + } + + static PyMethodDef PyStdOut_methods[] = { + {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, + PyDoc_STR("write(string) -> None")}, + {NULL, NULL} /* sentinel */ + }; + + static PyMemberDef PyStdOut_memberlist[] = { + {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0, + (char*)"flag indicating that a space needs to be printed; used by print"}, + {NULL} /* Sentinel */ + }; + + static PyTypeObject PyStdOut_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "PyOut", /*tp_name*/ + sizeof(PyStdOut), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)PyStdOut_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + /* softspace is writable: we must supply tp_setattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + PyStdOut_methods, /*tp_methods*/ + PyStdOut_memberlist, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + }; + + PyObject* newPyStdOut( std::string& out ) + { + PyStdOut* self = PyObject_New(PyStdOut, &PyStdOut_Type); + if (self) { + self->softspace = 0; + self->out=&out; + } + return (PyObject*)self; + } } -static PyObject * -PyStdOut_write(PyStdOut *self, PyObject *args) -{ - char *c; - int l; - if (!PyArg_ParseTuple(args, "t#:write",&c, &l)) - return NULL; - - //std::cerr << c ; - *(self->out)=*(self->out)+c; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyMethodDef PyStdOut_methods[] = { - {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, - PyDoc_STR("write(string) -> None")}, - {NULL, NULL} /* sentinel */ -}; - -static PyMemberDef PyStdOut_memberlist[] = { - {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0, - (char*)"flag indicating that a space needs to be printed; used by print"}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject PyStdOut_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "PyOut", /*tp_name*/ - sizeof(PyStdOut), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PyStdOut_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - PyObject_GenericGetAttr, /*tp_getattro*/ - /* softspace is writable: we must supply tp_setattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - PyStdOut_methods, /*tp_methods*/ - PyStdOut_memberlist, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - 0, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ -}; - -PyObject * newPyStdOut( std::string& out ) -{ - PyStdOut *self; - self = PyObject_New(PyStdOut, &PyStdOut_Type); - if (self == NULL) - return NULL; - self->softspace = 0; - self->out=&out; - return (PyObject*)self; -} - - ////////////////////////END PYTHON/////////////////////////// //============================================================================= /*! @@ -996,7 +996,6 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric PyObject* main_dict = PyModule_GetDict(main_mod); PyObject* obj = PyRun_String(aPyScript.ToCString(), Py_file_input, main_dict, NULL); - printf("%s\n", aPyScript.ToCString()); if (obj == NULL) { SetErrorCode("Error during executing of python script !!!"); @@ -1022,15 +1021,14 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric else coords = PyObject_CallFunction(func,(char*)"(d, d, d)", theParamMin, theParamMax, theParamStep ); - PyObject* new_stderr = NULL; - if (coords == NULL){ fflush(stderr); std::string err_description=""; - new_stderr = newPyStdOut(err_description); + PyObject* new_stderr = newPyStdOut(err_description); + PyObject* old_stderr = PySys_GetObject((char*)"stderr"); PySys_SetObject((char*)"stderr", new_stderr); PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + PySys_SetObject((char*)"stderr", old_stderr); Py_DECREF(new_stderr); MESSAGE("Can't evaluate coordCalculator()" << " error is " << err_description); SetErrorCode("Can't evaluate the expressions, please check them !!!"); diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 16e9ea4ca..0f90ef502 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -295,7 +295,7 @@ def ManageTransactions(theOpeName): ## Raise an Error, containing the Method_name, if Operation is Failed ## @ingroup l1_geomBuilder_auxiliary def RaiseIfFailed (Method_name, Operation): - if Operation.IsDone() == 0 and Operation.GetErrorCode() != "NOT_FOUND_ANY": + if not Operation.IsDone() and Operation.GetErrorCode() != "NOT_FOUND_ANY": raise RuntimeError, Method_name + " : " + Operation.GetErrorCode() ## Return list of variables value from salome notebook @@ -2414,7 +2414,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): anObj = self.CurvesOp.MakeCurveParametricNew(thexExpr,theyExpr,thezExpr,theParamMin,theParamMax,theParamStep,theCurveType) else: anObj = self.CurvesOp.MakeCurveParametric(thexExpr,theyExpr,thezExpr,theParamMin,theParamMax,theParamStep,theCurveType) - RaiseIfFailed("MakeSplineInterpolation", self.CurvesOp) + RaiseIfFailed("MakeCurveParametric", self.CurvesOp) anObj.SetParameters(Parameters) self._autoPublish(anObj, theName, "curve") return anObj From 6c9327744f9e03741a2371d5a7f90b1ab8744377 Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 1 Dec 2015 17:36:05 +0300 Subject: [PATCH 23/63] Additional change to previous commit to avoid memory corruption --- src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx index 8e3dab46b..229024df4 100644 --- a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx @@ -1026,6 +1026,7 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric std::string err_description=""; PyObject* new_stderr = newPyStdOut(err_description); PyObject* old_stderr = PySys_GetObject((char*)"stderr"); + Py_INCREF(old_stderr); PySys_SetObject((char*)"stderr", new_stderr); PyErr_Print(); PySys_SetObject((char*)"stderr", old_stderr); From f83b8bcd3ab6ba688e94f4ff1a2b971ae949386d Mon Sep 17 00:00:00 2001 From: skv Date: Wed, 2 Dec 2015 15:20:33 +0300 Subject: [PATCH 24/63] 0052994: Remove Extra Edges makes a shape invalid --- src/BlockFix/BlockFix_UnionEdges.cxx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/BlockFix/BlockFix_UnionEdges.cxx b/src/BlockFix/BlockFix_UnionEdges.cxx index 62a0307c5..4908e5455 100644 --- a/src/BlockFix/BlockFix_UnionEdges.cxx +++ b/src/BlockFix/BlockFix_UnionEdges.cxx @@ -161,7 +161,7 @@ static Standard_Boolean IsToMerge isSame = Standard_True; - for (; anIter1.More(); anIter1.Next()) { + for (; anIter1.More() && isSame; anIter1.Next()) { TopoDS_Face aFace1 = TopoDS::Face(anIter1.Value()); TopTools_ListIteratorOfListOfShape anIter2(aLst2); @@ -581,16 +581,24 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges, if (C.IsNull()) { // jfa for Mantis issue 0020228 if (PV1.Distance(PV2) > Precision::Confusion()) continue; - // closed chain - if (edge1.Orientation() == TopAbs_FORWARD) { - C = C1; - } else { - C = Handle(Geom_Circle)::DownCast(C1->Reversed()); + // closed chain. Make a closed circular edge starting from V1. + gp_Ax1 anAxis = C1->Axis(); + + if (edge1.Orientation() == TopAbs_REVERSED) { + anAxis.Reverse(); } + const gp_Pnt &aP0 = anAxis.Location(); + gp_Dir aDX(PV1.XYZ().Subtracted(aP0.XYZ())); + gp_Ax2 aNewAxis(aP0, anAxis.Direction(), aDX); + + C = new Geom_Circle(aNewAxis, C1->Radius()); + B.MakeEdge (E,C,Precision::Confusion()); B.Add(E,V1); B.Add(E,V2); + B.UpdateVertex(V1, 0., E, 0.); + B.UpdateVertex(V2, 2.*M_PI, E, 0.); } else { gp_Pnt P0 = C->Location(); From 80a0257573fd57f2301477bc15185ddc168a67f6 Mon Sep 17 00:00:00 2001 From: skv Date: Mon, 7 Dec 2015 15:38:50 +0300 Subject: [PATCH 25/63] 0023125: EDF 11112 GEOM: Choose the unity of length when exporting to STEP --- idl/STEPPlugin.idl | 21 +++- src/GEOM_I_Superv/GEOM_Superv_i.cc | 5 +- src/GEOM_SWIG/STEPPluginBuilder.py | 7 +- src/STEPPlugin/CMakeLists.txt | 3 + src/STEPPlugin/STEPPlugin_ExportDlg.cxx | 109 +++++++++++++++++++++ src/STEPPlugin/STEPPlugin_ExportDlg.h | 52 ++++++++++ src/STEPPlugin/STEPPlugin_ExportDriver.cxx | 40 +++++++- src/STEPPlugin/STEPPlugin_GUI.cxx | 10 +- src/STEPPlugin/STEPPlugin_IECallBack.cxx | 4 +- src/STEPPlugin/STEPPlugin_IExport.hxx | 6 ++ src/STEPPlugin/STEPPlugin_IOperations.cxx | 59 ++++++++++- src/STEPPlugin/STEPPlugin_IOperations.hxx | 23 ++++- src/STEPPlugin/STEPPlugin_IOperations_i.cc | 45 ++++++++- src/STEPPlugin/STEPPlugin_IOperations_i.hh | 3 +- src/STEPPlugin/STEPPlugin_msg_en.ts | 47 +++++++++ 15 files changed, 414 insertions(+), 20 deletions(-) create mode 100644 src/STEPPlugin/STEPPlugin_ExportDlg.cxx create mode 100644 src/STEPPlugin/STEPPlugin_ExportDlg.h mode change 100755 => 100644 src/STEPPlugin/STEPPlugin_IECallBack.cxx diff --git a/idl/STEPPlugin.idl b/idl/STEPPlugin.idl index 083016fab..ba1a74ec8 100644 --- a/idl/STEPPlugin.idl +++ b/idl/STEPPlugin.idl @@ -24,6 +24,23 @@ module GEOM { + /*! + * \brief Units of length + */ + enum length_unit + { + LU_INCH, + LU_MILLIMETER, + LU_FOOT, + LU_MILE, + LU_METER, + LU_KILOMETER, + LU_MILLIINCH, + LU_MICROMETER, + LU_CENTIMETER, + LU_MICROINCH + }; + /*! * \brief Interface for STEPPlugin modeling functions. */ @@ -34,9 +51,11 @@ module GEOM * * \param theObject Shape to be stored in the file. * \param theFileName Name of the file to store the given shape in. + * \param theUnit the length unit. */ void ExportSTEP( in GEOM::GEOM_Object theObject, - in string theFileName ); + in string theFileName, + in GEOM::length_unit theUnit); /*! * \brief Import a shape from the STEP file. diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.cc b/src/GEOM_I_Superv/GEOM_Superv_i.cc index 449a3c6b8..662b2c768 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.cc +++ b/src/GEOM_I_Superv/GEOM_Superv_i.cc @@ -3563,7 +3563,10 @@ void GEOM_Superv_i::ExportSTEP( GEOM::GEOM_Object_ptr theObject, beginService( " GEOM_Superv_i::ExportSTEP" ); MESSAGE("GEOM_Superv_i::ExportSTEP"); getSTEPPluginOp(); - mySTEPOp->ExportSTEP( theObject, theFileName ); + + const GEOM::length_unit aUnit = GEOM::LU_METER; + + mySTEPOp->ExportSTEP( theObject, theFileName, aUnit ); endService( " GEOM_Superv_i::ExportSTEP" ); } diff --git a/src/GEOM_SWIG/STEPPluginBuilder.py b/src/GEOM_SWIG/STEPPluginBuilder.py index 5501013f6..1ee4fc6c7 100644 --- a/src/GEOM_SWIG/STEPPluginBuilder.py +++ b/src/GEOM_SWIG/STEPPluginBuilder.py @@ -19,6 +19,7 @@ # from GEOM import ISTEPOperations +import GEOM # Engine Library Name __libraryName__ = "STEPPluginEngine" @@ -30,17 +31,19 @@ def GetSTEPPluginOperations(self): ## Export the given shape into a file with given name in STEP format. # @param theObject Shape to be stored in the file. # @param theFileName Name of the file to store the given shape in. +# @param theUnit the length unit (see GEOM::length_unit). In meters by default. # @ingroup l2_import_export -def ExportSTEP(self, theObject, theFileName): +def ExportSTEP(self, theObject, theFileName, theUnit=GEOM.LU_METER): """ Export the given shape into a file with given name in STEP format. Parameters: theObject Shape to be stored in the file. theFileName Name of the file to store the given shape in. + theUnit the length unit (see GEOM::length_unit). In meters by default. """ anOp = GetSTEPPluginOperations(self) - anOp.ExportSTEP(theObject, theFileName) + anOp.ExportSTEP(theObject, theFileName, theUnit) if anOp.IsDone() == 0: raise RuntimeError, "Export : " + anOp.GetErrorCode() pass diff --git a/src/STEPPlugin/CMakeLists.txt b/src/STEPPlugin/CMakeLists.txt index 513f54a74..52d210920 100644 --- a/src/STEPPlugin/CMakeLists.txt +++ b/src/STEPPlugin/CMakeLists.txt @@ -95,6 +95,7 @@ SET(STEPPluginEngine_HEADERS STEPPlugin_IExport.hxx STEPPlugin_IImport.hxx STEPPlugin_ImportDriver.hxx + STEPPlugin_ExportDlg.h STEPPlugin_ExportDriver.hxx STEPPlugin_IECallBack.hxx ) @@ -103,6 +104,7 @@ IF(SALOME_BUILD_GUI) # header files / to be processed by moc SET(_moc_HEADERS STEPPlugin_GUI.h + STEPPlugin_ExportDlg.h ) ENDIF() @@ -114,6 +116,7 @@ IF(SALOME_BUILD_GUI) SET(STEPPluginGUI_SOURCES STEPPlugin_GUI.cxx + STEPPlugin_ExportDlg.cxx ${_moc_SOURCES} ) ENDIF() diff --git a/src/STEPPlugin/STEPPlugin_ExportDlg.cxx b/src/STEPPlugin/STEPPlugin_ExportDlg.cxx new file mode 100644 index 000000000..2f8124b29 --- /dev/null +++ b/src/STEPPlugin/STEPPlugin_ExportDlg.cxx @@ -0,0 +1,109 @@ +// Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "STEPPlugin_ExportDlg.h" + +#include +#include +#include +#include + +//============================================================================= +// Constructor +//============================================================================= +STEPPlugin_ExportDlg::STEPPlugin_ExportDlg(QWidget *parent) + : SUIT_FileDlg (parent, false, true, true), + myUnitCB (0) +{ + QLabel* aUnitLabel = new QLabel(tr("STEP_LENGTH_UNITS"), this); + + myUnitCB = new QComboBox(this); + myUnitCB->addItem(tr("STEP_UNITS_KILOMETER"), GEOM::LU_KILOMETER); + myUnitCB->addItem(tr("STEP_UNITS_METER"), GEOM::LU_METER); + myUnitCB->addItem(tr("STEP_UNITS_CENTIMETER"), GEOM::LU_CENTIMETER); + myUnitCB->addItem(tr("STEP_UNITS_MILLIMETER"), GEOM::LU_MILLIMETER); + myUnitCB->addItem(tr("STEP_UNITS_MICROMETER"), GEOM::LU_MICROMETER); + myUnitCB->addItem(tr("STEP_UNITS_MILE"), GEOM::LU_MILE); + myUnitCB->addItem(tr("STEP_UNITS_FOOT"), GEOM::LU_FOOT); + myUnitCB->addItem(tr("STEP_UNITS_INCH"), GEOM::LU_INCH); + myUnitCB->addItem(tr("STEP_UNITS_MILLIINCH"), GEOM::LU_MILLIINCH); + myUnitCB->addItem(tr("STEP_UNITS_MICROINCH"), GEOM::LU_MICROINCH); + + // Meters by default. + myUnitCB->setCurrentIndex(1); + + layout()->addWidget(aUnitLabel); + layout()->addWidget(myUnitCB); +} + +//============================================================================= +// Destructor +//============================================================================= +STEPPlugin_ExportDlg::~STEPPlugin_ExportDlg() +{ +} + +//============================================================================= +// getUnits +//============================================================================= +GEOM::length_unit STEPPlugin_ExportDlg::getUnits() const +{ + const GEOM::length_unit anUnit = + (GEOM::length_unit) myUnitCB->itemData(myUnitCB->currentIndex()).toInt(); + + return anUnit; +} + +//============================================================================= +// getFileName +//============================================================================= +QString STEPPlugin_ExportDlg::getFileName(const QString &theInitial, + const QString &theFilters, + const QString &theCaption, + QWidget *theParent, + GEOM::length_unit &theUnits) +{ + QStringList aFls = theFilters.split(";;", QString::SkipEmptyParts); + QString aTmpFileName = theInitial; + + aTmpFileName = aTmpFileName.simplified(); + aTmpFileName = + aTmpFileName.replace(QRegExp("\\*"), "").replace(QRegExp("\\?"), ""); + + STEPPlugin_ExportDlg aDlg(theParent); + + aDlg.setFileMode(AnyFile); + aDlg.setFilters(aFls); + aDlg.setWindowTitle(theCaption); + + if (!aTmpFileName.isEmpty()) { + aDlg.processPath(aTmpFileName); + } + + QString aFileName; + + if (aDlg.exec() == QDialog::Accepted) { + aFileName = aDlg.selectedFile(); + theUnits = aDlg.getUnits(); + } + + QApplication::processEvents(); + + return aFileName; +} diff --git a/src/STEPPlugin/STEPPlugin_ExportDlg.h b/src/STEPPlugin/STEPPlugin_ExportDlg.h new file mode 100644 index 000000000..d310484d3 --- /dev/null +++ b/src/STEPPlugin/STEPPlugin_ExportDlg.h @@ -0,0 +1,52 @@ +// Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef STEPPlugin_ExportDlg_H +#define STEPPlugin_ExportDlg_H + +#include +#include +#include CORBA_CLIENT_HEADER(STEPPlugin) + +class QComboBox; + +class STEPPlugin_ExportDlg: public SUIT_FileDlg +{ + Q_OBJECT + +public: + + STEPPlugin_ExportDlg(QWidget *parent); + ~STEPPlugin_ExportDlg(); + + GEOM::length_unit getUnits() const; + + static QString getFileName(const QString &theInitial, + const QString &theFilters, + const QString &theCaption, + QWidget *theParent, + GEOM::length_unit &theUnits); + +private: + + QComboBox *myUnitCB; + +}; + +#endif // STEPPlugin_ExportDlg_H diff --git a/src/STEPPlugin/STEPPlugin_ExportDriver.cxx b/src/STEPPlugin/STEPPlugin_ExportDriver.cxx index 8f5f0db18..0adef6012 100644 --- a/src/STEPPlugin/STEPPlugin_ExportDriver.cxx +++ b/src/STEPPlugin/STEPPlugin_ExportDriver.cxx @@ -20,6 +20,7 @@ // internal includes #include "STEPPlugin_ExportDriver.hxx" #include "STEPPlugin_IExport.hxx" +#include "STEPPlugin_IOperations.hxx" // KERNEL includes #include @@ -74,6 +75,43 @@ Standard_Integer STEPPlugin_ExportDriver::Execute( TFunction_Logbook& log ) cons aFunction->SetValue( aShape ); TCollection_AsciiString aFileName = aData.GetFileName(); + Standard_Integer anUnit = aData.GetUnit(); + TCollection_AsciiString aWriteUnit; + + switch (anUnit) { + case STEPPlugin_IOperations::LengthUnit_Inch: + aWriteUnit = "INCH"; + break; + case STEPPlugin_IOperations::LengthUnit_Millimeter: + aWriteUnit = "MM"; + break; + case STEPPlugin_IOperations::LengthUnit_Foot: + aWriteUnit = "FT"; + break; + case STEPPlugin_IOperations::LengthUnit_Mile: + aWriteUnit = "MI"; + break; + case STEPPlugin_IOperations::LengthUnit_Meter: + aWriteUnit = "M"; + break; + case STEPPlugin_IOperations::LengthUnit_Kilometer: + aWriteUnit = "KM"; + break; + case STEPPlugin_IOperations::LengthUnit_Milliinch: + aWriteUnit = "MIL"; + break; + case STEPPlugin_IOperations::LengthUnit_Micrometer: + aWriteUnit = "UM"; + break; + case STEPPlugin_IOperations::LengthUnit_Centimeter: + aWriteUnit = "CM"; + break; + case STEPPlugin_IOperations::LengthUnit_Microinch: + aWriteUnit = "UIN"; + break; + default: + return 0; + } MESSAGE("Export STEP into file " << aFileName.ToCString()); @@ -86,7 +124,7 @@ Standard_Integer STEPPlugin_ExportDriver::Execute( TFunction_Logbook& log ) cons //VRV: OCC 4.0 migration STEPControl_Writer aWriter; Interface_Static::SetCVal("xstep.cascade.unit","M"); - Interface_Static::SetCVal("write.step.unit", "M"); + Interface_Static::SetCVal("write.step.unit", aWriteUnit.ToCString()); Interface_Static::SetIVal("write.step.nonmanifold", 1); status = aWriter.Transfer( aShape, STEPControl_AsIs ); //VRV: OCC 4.0 migration diff --git a/src/STEPPlugin/STEPPlugin_GUI.cxx b/src/STEPPlugin/STEPPlugin_GUI.cxx index c8f0300e3..5543266d7 100644 --- a/src/STEPPlugin/STEPPlugin_GUI.cxx +++ b/src/STEPPlugin/STEPPlugin_GUI.cxx @@ -37,6 +37,7 @@ #include "GEOMBase.h" #include "GEOM_Displayer.h" #include "GEOM_GenericObjPtr.h" +#include "STEPPlugin_ExportDlg.h" #include #include CORBA_SERVER_HEADER(STEPPlugin) @@ -250,11 +251,12 @@ bool STEPPlugin_GUI::exportSTEP( SUIT_Desktop* parent ) if ( CORBA::is_nil( obj ) ) continue; - QString fileName = app->getFileName( false, - QString( io->getName() ), + GEOM::length_unit anUnit; + QString fileName = STEPPlugin_ExportDlg::getFileName + (QString( io->getName() ), tr( "STEP_FILES" ), tr( "EXPORT_TITLE" ), - parent ); + parent, anUnit); if ( fileName.isEmpty() ) return false; @@ -268,7 +270,7 @@ bool STEPPlugin_GUI::exportSTEP( SUIT_Desktop* parent ) app->putInfo( tr( "GEOM_PRP_EXPORT" ).arg( fileName ) ); transaction.start(); - stepOp->ExportSTEP( obj, fileName.toUtf8().constData() ); + stepOp->ExportSTEP( obj, fileName.toUtf8().constData(), anUnit); if ( stepOp->IsDone() ) { diff --git a/src/STEPPlugin/STEPPlugin_IECallBack.cxx b/src/STEPPlugin/STEPPlugin_IECallBack.cxx old mode 100755 new mode 100644 index bc5c0ff81..ac0869716 --- a/src/STEPPlugin/STEPPlugin_IECallBack.cxx +++ b/src/STEPPlugin/STEPPlugin_IECallBack.cxx @@ -52,7 +52,9 @@ STEPPlugin_IECallBack::Export( int theDocId, const TCollection_AsciiString& theFormatName ) { STEPPlugin_IOperations* aPluginOperations = STEPPlugin_OperationsCreator::get( GetEngine(), theDocId ); - aPluginOperations->ExportSTEP( theOriginal, theFileName ); + const STEPPlugin_IOperations::LengthUnit aUnit = STEPPlugin_IOperations::LengthUnit_Meter; + + aPluginOperations->ExportSTEP( theOriginal, theFileName, aUnit ); return true; } diff --git a/src/STEPPlugin/STEPPlugin_IExport.hxx b/src/STEPPlugin/STEPPlugin_IExport.hxx index 020b573ad..77f01392b 100644 --- a/src/STEPPlugin/STEPPlugin_IExport.hxx +++ b/src/STEPPlugin/STEPPlugin_IExport.hxx @@ -24,6 +24,7 @@ #define EXPORTSTEP_ARG_ORIGINAL 1 #define EXPORTSTEP_ARG_FILENAME 2 +#define EXPORTSTEP_ARG_UNIT 3 class STEPPlugin_IExport { @@ -40,6 +41,11 @@ public: { _func->SetString( EXPORTSTEP_ARG_FILENAME, theFileName ); } TCollection_AsciiString GetFileName() { return _func->GetString( EXPORTSTEP_ARG_FILENAME ); } + + void SetUnit(const Standard_Integer theUnit) + { _func->SetInteger(EXPORTSTEP_ARG_UNIT, theUnit); } + Standard_Integer GetUnit() + { return _func->GetInteger(EXPORTSTEP_ARG_UNIT); } private: Handle(GEOM_Function) _func; diff --git a/src/STEPPlugin/STEPPlugin_IOperations.cxx b/src/STEPPlugin/STEPPlugin_IOperations.cxx index 86d1055e3..72064e8e3 100644 --- a/src/STEPPlugin/STEPPlugin_IOperations.cxx +++ b/src/STEPPlugin/STEPPlugin_IOperations.cxx @@ -54,18 +54,66 @@ STEPPlugin_IOperations::~STEPPlugin_IOperations() MESSAGE( "STEPPlugin_IOperations::~STEPPlugin_IOperations" ); } +//============================================================================= +/*! + * + */ +//============================================================================= +static GEOM::TPythonDump& operator<< + (GEOM::TPythonDump &theDump, + const STEPPlugin_IOperations::LengthUnit theState) +{ + switch (theState) { + case STEPPlugin_IOperations::LengthUnit_Inch: + theDump << "GEOM.LU_INCH"; + break; + case STEPPlugin_IOperations::LengthUnit_Millimeter: + theDump << "GEOM.LU_MILLIMETER"; + break; + case STEPPlugin_IOperations::LengthUnit_Foot: + theDump << "GEOM.LU_FOOT"; + break; + case STEPPlugin_IOperations::LengthUnit_Mile: + theDump << "GEOM.LU_MILE"; + break; + case STEPPlugin_IOperations::LengthUnit_Meter: + theDump << "GEOM.LU_METER"; + break; + case STEPPlugin_IOperations::LengthUnit_Kilometer: + theDump << "GEOM.LU_KILOMETER"; + break; + case STEPPlugin_IOperations::LengthUnit_Milliinch: + theDump << "GEOM.LU_MILLIINCH"; + break; + case STEPPlugin_IOperations::LengthUnit_Micrometer: + theDump << "GEOM.LU_MICROMETER"; + break; + case STEPPlugin_IOperations::LengthUnit_Centimeter: + theDump << "GEOM.LU_CENTIMETER"; + break; + case STEPPlugin_IOperations::LengthUnit_Microinch: + theDump << "GEOM.LU_MICROINCH"; + break; + default: + break; + } + + return theDump; +} + //============================================================================= /*! * ExportSTEP * Export a shape to STEP format * \param theOriginal The shape to export * \param theFileName The name of the file to exported - * \param theIsASCII The format of the exported file (ASCII or Binary) - * \param theDeflection The deflection of the shape to exported + * \param theUnit the length unit */ //============================================================================= -void STEPPlugin_IOperations::ExportSTEP( const Handle(GEOM_Object) theOriginal, - const TCollection_AsciiString& theFileName ) +void STEPPlugin_IOperations::ExportSTEP + (const Handle(GEOM_Object) theOriginal, + const TCollection_AsciiString &theFileName, + const LengthUnit theUnit) { SetErrorCode(KO); if( theOriginal.IsNull() ) return; @@ -87,6 +135,7 @@ void STEPPlugin_IOperations::ExportSTEP( const Handle(GEOM_Object) theOrigi STEPPlugin_IExport aCI( aFunction ); aCI.SetOriginal( aRefFunction ); aCI.SetFileName( theFileName ); + aCI.SetUnit( theUnit ); //Perform the Export try { @@ -104,7 +153,7 @@ void STEPPlugin_IOperations::ExportSTEP( const Handle(GEOM_Object) theOrigi //Make a Python command GEOM::TPythonDump(aFunction) << "geompy.ExportSTEP(" << theOriginal << ", \"" - << theFileName.ToCString() << "\" )"; + << theFileName.ToCString() << "\", " << theUnit << " )"; SetErrorCode(OK); } diff --git a/src/STEPPlugin/STEPPlugin_IOperations.hxx b/src/STEPPlugin/STEPPlugin_IOperations.hxx index ca81fac29..92b3f160e 100644 --- a/src/STEPPlugin/STEPPlugin_IOperations.hxx +++ b/src/STEPPlugin/STEPPlugin_IOperations.hxx @@ -29,12 +29,33 @@ class STEPPLUGINENGINE_EXPORT STEPPlugin_IOperations: public GEOMImpl_IBaseIEOperations { + +public: + + /*! + * \brief Units of length + */ + enum LengthUnit + { + LengthUnit_Inch, + LengthUnit_Millimeter, + LengthUnit_Foot, + LengthUnit_Mile, + LengthUnit_Meter, + LengthUnit_Kilometer, + LengthUnit_Milliinch, + LengthUnit_Micrometer, + LengthUnit_Centimeter, + LengthUnit_Microinch + }; + + public: STEPPlugin_IOperations( GEOM_Engine*, int ); ~STEPPlugin_IOperations(); void ExportSTEP( const Handle(GEOM_Object), - const TCollection_AsciiString& ); + const TCollection_AsciiString&, const LengthUnit ); Handle(TColStd_HSequenceOfTransient) ImportSTEP( const TCollection_AsciiString&, const bool ); diff --git a/src/STEPPlugin/STEPPlugin_IOperations_i.cc b/src/STEPPlugin/STEPPlugin_IOperations_i.cc index 7eeee1a94..fba3ce031 100644 --- a/src/STEPPlugin/STEPPlugin_IOperations_i.cc +++ b/src/STEPPlugin/STEPPlugin_IOperations_i.cc @@ -53,10 +53,12 @@ STEPPlugin_IOperations_i::~STEPPlugin_IOperations_i() * Export a shape to STEP format * \param theOriginal The shape to export * \param theFileName The name of the exported file + * \param theUnit the length unit. */ //============================================================================= -void STEPPlugin_IOperations_i::ExportSTEP( GEOM::GEOM_Object_ptr theOriginal, - const char* theFileName ) +void STEPPlugin_IOperations_i::ExportSTEP(GEOM::GEOM_Object_ptr theOriginal, + const char* theFileName, + GEOM::length_unit theUnit) { // duplicate the original shape GEOM::GEOM_Object_var aGEOMObject = GEOM::GEOM_Object::_duplicate( theOriginal ); @@ -68,8 +70,45 @@ void STEPPlugin_IOperations_i::ExportSTEP( GEOM::GEOM_Object_ptr theOriginal, Handle(GEOM_Object) anOriginal = GetObjectImpl( theOriginal ); if (anOriginal.IsNull()) return; + STEPPlugin_IOperations::LengthUnit aUnit; + + switch (theUnit) { + case GEOM::LU_INCH: + aUnit = STEPPlugin_IOperations::LengthUnit_Inch; + break; + case GEOM::LU_MILLIMETER: + aUnit = STEPPlugin_IOperations::LengthUnit_Millimeter; + break; + case GEOM::LU_FOOT: + aUnit = STEPPlugin_IOperations::LengthUnit_Foot; + break; + case GEOM::LU_MILE: + aUnit = STEPPlugin_IOperations::LengthUnit_Mile; + break; + case GEOM::LU_METER: + aUnit = STEPPlugin_IOperations::LengthUnit_Meter; + break; + case GEOM::LU_KILOMETER: + aUnit = STEPPlugin_IOperations::LengthUnit_Kilometer; + break; + case GEOM::LU_MILLIINCH: + aUnit = STEPPlugin_IOperations::LengthUnit_Milliinch; + break; + case GEOM::LU_MICROMETER: + aUnit = STEPPlugin_IOperations::LengthUnit_Micrometer; + break; + case GEOM::LU_CENTIMETER: + aUnit = STEPPlugin_IOperations::LengthUnit_Centimeter; + break; + case GEOM::LU_MICROINCH: + aUnit = STEPPlugin_IOperations::LengthUnit_Microinch; + break; + default: + return; + } + //Export the shape to the file - GetOperations()->ExportSTEP( anOriginal, theFileName ); + GetOperations()->ExportSTEP( anOriginal, theFileName, aUnit ); } //============================================================================= diff --git a/src/STEPPlugin/STEPPlugin_IOperations_i.hh b/src/STEPPlugin/STEPPlugin_IOperations_i.hh index e2c51c79a..16e000909 100644 --- a/src/STEPPlugin/STEPPlugin_IOperations_i.hh +++ b/src/STEPPlugin/STEPPlugin_IOperations_i.hh @@ -43,7 +43,8 @@ public: STEPPlugin_IOperations* theImpl ); ~STEPPlugin_IOperations_i(); - void ExportSTEP( GEOM::GEOM_Object_ptr, const char* ); + void ExportSTEP( GEOM::GEOM_Object_ptr, const char*, + GEOM::length_unit ); GEOM::ListOfGO* ImportSTEP( const char*, const bool ); char* ReadValue( const char*, const char* ); diff --git a/src/STEPPlugin/STEPPlugin_msg_en.ts b/src/STEPPlugin/STEPPlugin_msg_en.ts index d24fc9014..47d15c8f8 100644 --- a/src/STEPPlugin/STEPPlugin_msg_en.ts +++ b/src/STEPPlugin/STEPPlugin_msg_en.ts @@ -48,4 +48,51 @@ Ignoring units will cause model scaling (as dimensions are supposed to be specified in meters). + + STEPPlugin_ExportDlg + + STEP_LENGTH_UNITS + Length units + + + STEP_UNITS_INCH + inch + + + STEP_UNITS_MILLIMETER + millimeter + + + STEP_UNITS_FOOT + foot + + + STEP_UNITS_MILE + mile + + + STEP_UNITS_METER + meter + + + STEP_UNITS_KILOMETER + kilometer + + + STEP_UNITS_MILLIINCH + milliinch + + + STEP_UNITS_MICROMETER + micrometer + + + STEP_UNITS_CENTIMETER + centimeter + + + STEP_UNITS_MICROINCH + microinch + + From c389c09498e5046628be5d9c16413bad71fab6f5 Mon Sep 17 00:00:00 2001 From: skv Date: Thu, 24 Dec 2015 10:30:49 +0300 Subject: [PATCH 26/63] 0022870: EDF 10111 GEOM: MakePipe of a wire along an edge fails. --- src/GEOMImpl/GEOMImpl_PipeDriver.cxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx index cf660675f..ef5b07e79 100644 --- a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx @@ -108,6 +108,8 @@ #define GROUP_SIDE2 3 #define GROUP_OTHER 4 +static const Standard_Real TolPipeSurf = 5.e-4; + static bool FillGroups(const TopTools_SequenceOfShape *theGroups, const TopTools_IndexedMapOfShape &theIndices, Handle(TColStd_HArray1OfInteger) *theGroupIds); @@ -182,7 +184,8 @@ static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder) Standard_Boolean isDone = theBuilder.IsDone(); - if (!isDone) { + if (!isDone || + theBuilder.ErrorOnSurface() > TolPipeSurf) { // Try to use Descrete Trihedron mode. theBuilder.SetDiscreteMode(); theBuilder.Build(); @@ -3124,7 +3127,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath); BRepOffsetAPI_MakePipe aMkPipe(aWirePath, aShapeBase, theBestMode); - if (aMkPipe.IsDone()) { + if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) { aShape = aMkPipe.Shape(); if (!CreateGroups(aShapeBase, aWirePath, aMkPipe, aCI)) { From 907035f22e8ef9bb33e3dafecb3d71c1061c0ed6 Mon Sep 17 00:00:00 2001 From: skv Date: Mon, 28 Dec 2015 12:01:54 +0300 Subject: [PATCH 27/63] 0052973: Wrong order publication objects in object browser --- src/GEOM/GEOM_Engine.cxx | 148 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 140 insertions(+), 8 deletions(-) diff --git a/src/GEOM/GEOM_Engine.cxx b/src/GEOM/GEOM_Engine.cxx index 0859c2850..e7921bed4 100644 --- a/src/GEOM/GEOM_Engine.cxx +++ b/src/GEOM/GEOM_Engine.cxx @@ -88,6 +88,7 @@ static int MYDEBUG = 0; typedef std::map< TCollection_AsciiString, TCollection_AsciiString > TSting2StringMap; typedef std::map< TCollection_AsciiString, TObjectData > TSting2ObjDataMap; typedef std::map< TCollection_AsciiString, TObjectData* > TSting2ObjDataPtrMap; +typedef std::map< int, std::list < int > > TIntToListIntMap; static GEOM_Engine* TheEngine = NULL; @@ -123,6 +124,11 @@ bool ProcessFunction(Handle(GEOM_Function)& theFunction, std::set& theIgnoreObjs, bool& theIsDumpCollected); +static int GetTag(const TCollection_AsciiString &theEntry); + +static void FillMapOfRef(const Handle(GEOM_Function) &theFunction, + TIntToListIntMap &theRefMap); + void ReplaceVariables(TCollection_AsciiString& theCommand, const TVariablesList& theVariables); @@ -148,6 +154,12 @@ void PublishObject (TObjectData& theObjectData, std::map< int, TCollection_AsciiString >& theEntryToCmdMap, std::set& theMapOfPublished); +static TCollection_AsciiString GetPublishCommands + (const int theTag, + const std::map< int, TCollection_AsciiString > &theEntryToCmdMap, + const TIntToListIntMap &theMapRefs, + std::set< int > &thePublished); + //================================================================================ /*! * \brief Fix up the name of python variable @@ -674,6 +686,7 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, // Mantis issue 0020768 Standard_Integer objectCounter = 0; Resource_DataMapOfAsciiStringAsciiString aNameToEntry; + TIntToListIntMap aRefMap; if (aDoc->Main().FindAttribute(GEOM_Function::GetFunctionTreeID(), aRoot)) { TDataStd_ChildNodeIterator Itr(aRoot); @@ -702,6 +715,10 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, continue; // aCurScript is already at the end of aFuncScript aFuncScript += aCurScript; } + + // Fill the map of references. + FillMapOfRef(aFunction, aRefMap); + if (isDumpCollected ) { // Replace entries by the names ReplaceEntriesByNames( aFuncScript, aEntry2ObjData, isPublished, @@ -717,9 +734,16 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, aNameToEntry, anEntryToCmdMap, anIgnoreObjMap ); } // add publishing commands to the script + std::set< int > aPublished; std::map< int, TCollection_AsciiString >::iterator anEntryToCmd = anEntryToCmdMap.begin(); - for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd ) - aFuncScript += anEntryToCmd->second; + + for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd ) { + const TCollection_AsciiString aPublishCmds = + GetPublishCommands(anEntryToCmd->first, anEntryToCmdMap, + aRefMap, aPublished); + + aFuncScript += aPublishCmds; + } // PTv, 0020001 add result objects from RestoreGivenSubShapes into ignore list, // because they will be published during command execution @@ -772,9 +796,16 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, aNameToEntry, anEntryToCmdMap, anIgnoreObjMap ); } // add publishing commands to the script + std::set< int > aPublished; std::map< int, TCollection_AsciiString >::iterator anEntryToCmd = anEntryToCmdMap.begin(); - for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd ) - aScript += anEntryToCmd->second; + + for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd ) { + const TCollection_AsciiString aPublishCmds = + GetPublishCommands(anEntryToCmd->first, anEntryToCmdMap, + aRefMap, aPublished); + + aScript += aPublishCmds; + } } //RNV: issue 16219: EDF PAL 469: "RemoveFromStudy" Function @@ -1197,6 +1228,64 @@ bool ProcessFunction(Handle(GEOM_Function)& theFunction, return true; } +//============================================================================= +/*! + * GetTag: Returns the tag from entry + */ +//============================================================================= +int GetTag(const TCollection_AsciiString &theEntry) +{ + const int aGeomObjDepth = 3; + const int aTag = theEntry.Token(":", aGeomObjDepth).IntegerValue(); + + return aTag; +} + +//============================================================================= +/*! + * FillMapOfRef: Fill the map of references + */ +//============================================================================= +void FillMapOfRef(const Handle(GEOM_Function) &theFunction, + TIntToListIntMap &theRefMap) +{ + TDF_LabelSequence aSeq; + TCollection_AsciiString anObjEntry; + int anObjTag; + + TDF_Tool::Entry(theFunction->GetOwnerEntry(), anObjEntry); + anObjTag = GetTag(anObjEntry); + theFunction->GetDependency(aSeq); + + const Standard_Integer aLen = aSeq.Length(); + Standard_Integer i; + + for (i = 1; i <= aLen; i++) { + TDF_Label aRefLabel = aSeq.Value(i); + Handle(TDF_Reference) aRef; + + if (aRefLabel.FindAttribute(TDF_Reference::GetID(), aRef)) { + if (!aRef.IsNull() && !aRef->Get().IsNull()) { + Handle(TDataStd_TreeNode) aT; + + if (TDataStd_TreeNode::Find(aRef->Get(), aT)) { + TDF_Label aDepLabel = aT->Label(); + Handle(GEOM_Function) aRefFunct = GEOM_Function::GetFunction(aDepLabel); + + if (!aRefFunct.IsNull()) { + // Get entry of the referenced object. + TDF_Tool::Entry(aRefFunct->GetOwnerEntry(), anObjEntry); + + const int aRefTag = GetTag(anObjEntry); + + theRefMap[anObjTag].push_back(aRefTag); + } + } + } + } + } +} + //============================================================================= /*! * FindEntries: Returns a sequence of start/end positions of entries in the string @@ -1726,8 +1815,6 @@ void PublishObject (TObjectData& theObjectData, if ( stEntry2DataPtr != theStEntry2ObjDataPtr.end() ) aFatherData = stEntry2DataPtr->second; - const int geomObjDepth = 3; - // treat multiply published object if ( theObjectData._pyName.IsEmpty() ) { @@ -1741,7 +1828,7 @@ void PublishObject (TObjectData& theObjectData, aCreationCommand += theObjectData._pyName + " = " + data0._pyName; // store aCreationCommand before publishing commands - int tag = theObjectData._entry.Token( ":", geomObjDepth ).IntegerValue(); + int tag = GetTag(theObjectData._entry); theEntryToCmdMap.insert( std::make_pair( tag + 2*theEntry2ObjData.size(), aCreationCommand )); } @@ -1756,12 +1843,57 @@ void PublishObject (TObjectData& theObjectData, aCommand += theObjectData._pyName + ", '" + theObjectData._name + "' )"; // bind a command to the study entry - int tag = theObjectData._entry.Token( ":", geomObjDepth ).IntegerValue(); + int tag = GetTag(theObjectData._entry); theEntryToCmdMap.insert( std::make_pair( tag, aCommand )); theObjectData._studyEntry.Clear(); // not to publish any more } +//================================================================================ +/*! + * \brief Returns the string of publishing commands. Take into account that + * references should be published prior to the objects refer to them. + */ +//================================================================================ +TCollection_AsciiString GetPublishCommands + (const int theTag, + const std::map< int, TCollection_AsciiString > &theEntryToCmdMap, + const TIntToListIntMap &theMapRefs, + std::set< int > &thePublished) +{ + TCollection_AsciiString aResult; + + if (!thePublished.count(theTag)) { + // This object is not published yet. + std::map< int, TCollection_AsciiString >::const_iterator anIt = + theEntryToCmdMap.find(theTag); + + if (anIt != theEntryToCmdMap.end()) { + // There is a pubish cmd. + TIntToListIntMap::const_iterator aRefIt = theMapRefs.find(theTag); + + if (aRefIt != theMapRefs.end()) { + // Recursively publish all references. + std::list< int >::const_iterator aRefTagIt = aRefIt->second.begin(); + + for(; aRefTagIt != aRefIt->second.end(); ++aRefTagIt) { + const TCollection_AsciiString aRefCmd = GetPublishCommands + (*aRefTagIt, theEntryToCmdMap, theMapRefs, thePublished); + + aResult += aRefCmd; + } + } + + // Add the object command. + aResult += anIt->second; + } + + thePublished.insert(theTag); + } + + return aResult; +} + //================================================================================ /*! * \brief Constructor From 92478173383e7af3ec38442c96f4aa2f503461a1 Mon Sep 17 00:00:00 2001 From: skv Date: Tue, 29 Dec 2015 13:01:30 +0300 Subject: [PATCH 28/63] 0052954: Get In Place does not work --- src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index 3ed4513ec..65716670c 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -4636,6 +4637,8 @@ static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2) U = U11+range*2.0/3.0; gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length + C2 = new Geom_TrimmedCurve(C2, U21, U22); + if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22) return false; From f069900cfc6024896d23e8a37a898150e158c677 Mon Sep 17 00:00:00 2001 From: skv Date: Tue, 29 Dec 2015 13:20:06 +0300 Subject: [PATCH 29/63] 0052956: Shape Statistics on Group of edges problem --- src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx index 9387cf4a8..681c0bab5 100644 --- a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx @@ -311,9 +311,9 @@ void MeasureGUI_ShapeStatisticsDlg::updateTypes( QList theShap if ( hasEdges != 0 ) hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_EDGE ) > 0; if ( hasFaces != 0 ) - hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_FACE ) > 0; + hasFaces = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_FACE ) > 0; if ( hasSolids != 0 ) - hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_SOLID ) > 0; + hasSolids = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_SOLID ) > 0; } fillTypes( hasEdges, hasFaces, hasSolids ); } From 6b60614b1f2a8e1c457002f78e3932590510076a Mon Sep 17 00:00:00 2001 From: skv Date: Wed, 30 Dec 2015 17:12:45 +0300 Subject: [PATCH 30/63] 0052845: GetInPlace selection option does not work in Create Group dialog --- src/GroupGUI/GroupGUI_GroupDlg.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/GroupGUI/GroupGUI_GroupDlg.cxx b/src/GroupGUI/GroupGUI_GroupDlg.cxx index 5bf351f85..aec21881f 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.cxx +++ b/src/GroupGUI/GroupGUI_GroupDlg.cxx @@ -881,6 +881,12 @@ int GroupGUI_GroupDlg::getSelectedSubshapes (TColStd_IndexedMapOfInteger& theMap TopoDS_Shape aShape; if (GEOMBase::GetShape(aGeomObj, aShape)) { if (aGeomObj->GetType() == GEOM_GROUP || aShape.ShapeType() == getShapeType()) { + if (subSelectionWay() != ALL_SUBSHAPES && + GEOMBase::GetName(aGeomObj) == myShape2Name->text()) { + // Skip selected in place object. + continue; + } + TopTools_IndexedMapOfShape aMainMap; TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj); TopExp::MapShapes(aMainShape, aMainMap); From 9c396f205960397217fc58f263d49135b7697b1a Mon Sep 17 00:00:00 2001 From: Paul RASCLE Date: Fri, 8 Jan 2016 16:38:11 +0100 Subject: [PATCH 31/63] remise en marche du plugin t_shape_fluid --- CMakeLists.txt | 1 + src/CMakeLists.txt | 2 +- src/GEOMGUI/GEOM_msg_en.ts | 2 +- src/GEOMGUI/GEOM_msg_fr.ts | 2 +- src/Tools/geom_plugins.py | 4 +- src/Tools/t_shape/CMakeLists.txt | 18 ++++- src/Tools/t_shape/__init__.py | 1 + src/Tools/t_shape/t_shape_builder.py | 2 +- src/Tools/t_shape/t_shape_dialog.py | 16 ++-- src/Tools/t_shape/t_shape_dialog.ui | 76 ++++++++++++++---- src/Tools/t_shape/t_shape_dialog_ui.py | 103 ------------------------- 11 files changed, 96 insertions(+), 131 deletions(-) create mode 100644 src/Tools/t_shape/__init__.py delete mode 100644 src/Tools/t_shape/t_shape_dialog_ui.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 828cfb7f4..4dc80fd57 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,6 +127,7 @@ IF(SALOME_BUILD_GUI) # Qt4 FIND_PACKAGE(SalomeQt4 REQUIRED COMPONENTS QtCore QtGui QtXml) + FIND_PACKAGE(SalomePyQt4) ENDIF(SALOME_BUILD_GUI) ## diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bd7e3428d..13d33e444 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,7 +24,7 @@ SET(SUBDIRS_COMMON ARCHIMEDE BlockFix GEOMAlgo SKETCHER GEOM ShHealOper GEOMUtils XAO XAO_Swig GEOMImpl GEOM_I GEOMClient GEOM_I_Superv GEOM_SWIG GEOM_PY AdvancedEngine OCC2VTK - STLPlugin BREPPlugin STEPPlugin IGESPlugin XAOPlugin VTKPlugin + STLPlugin BREPPlugin STEPPlugin IGESPlugin XAOPlugin VTKPlugin Tools ) ## diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 2f225edbd..5a094f303 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -5350,7 +5350,7 @@ shells and solids on the other hand. GEOM_PLUGINS_OTHER - Other + Python Plugins SHOW_ONLY_SELECTED diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 1a1231364..01acd20ca 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -5342,7 +5342,7 @@ le paramètre '%1' aux préférences du module Géométrie. GEOM_PLUGINS_OTHER - Autre + Plugins Python SHOW_ONLY_SELECTED diff --git a/src/Tools/geom_plugins.py b/src/Tools/geom_plugins.py index 00ad4f149..a1f6ab394 100644 --- a/src/Tools/geom_plugins.py +++ b/src/Tools/geom_plugins.py @@ -22,8 +22,8 @@ import salome_pluginsmanager def t_shape_fluid(context): - import t_shape_builder - import t_shape_dialog + from t_shape import t_shape_builder + from t_shape import t_shape_dialog import xalome from PyQt4.QtGui import QMessageBox activeStudy = context.study diff --git a/src/Tools/t_shape/CMakeLists.txt b/src/Tools/t_shape/CMakeLists.txt index 35cc00554..4701fc26d 100644 --- a/src/Tools/t_shape/CMakeLists.txt +++ b/src/Tools/t_shape/CMakeLists.txt @@ -17,16 +17,28 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +INCLUDE(UsePyQt4) + # --- scripts --- # scripts / static SET(plugin_SCRIPTS + __init__.py t_shape_builder.py t_shape_dialog.py t_shape_dialog.ui - t_shape_dialog_ui.py - ) + ) + +# uic files / to be processed by pyuic +SET(_pyuic_files + t_shape_dialog.ui +) + +# scripts / pyuic wrappings +PYQT4_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) + # --- rules --- -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}/t_shape) +SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_GEOM_INSTALL_PLUGINS}/t_shape) +SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_GEOM_INSTALL_PLUGINS}/t_shape) \ No newline at end of file diff --git a/src/Tools/t_shape/__init__.py b/src/Tools/t_shape/__init__.py new file mode 100644 index 000000000..40a96afc6 --- /dev/null +++ b/src/Tools/t_shape/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/src/Tools/t_shape/t_shape_builder.py b/src/Tools/t_shape/t_shape_builder.py index 09a818b29..3082dc849 100644 --- a/src/Tools/t_shape/t_shape_builder.py +++ b/src/Tools/t_shape/t_shape_builder.py @@ -1,4 +1,4 @@ -# -*- coding: iso-8859-1 -*- +# -*- coding: utf-8 -*- import sys import salome diff --git a/src/Tools/t_shape/t_shape_dialog.py b/src/Tools/t_shape/t_shape_dialog.py index ce6032994..9fb4f9b28 100644 --- a/src/Tools/t_shape/t_shape_dialog.py +++ b/src/Tools/t_shape/t_shape_dialog.py @@ -34,19 +34,23 @@ class TShapeDialog(QtGui.QDialog): self.ui.setupUi(self) self.show() self._wasOk = False - self.ui.doubleSpinBox_5.setEnabled(False) + self.ui.dsb_solidThickness.setEnabled(False) self.ui.label_5.setEnabled(False) + self.ui.dsb_bigRadius.setValue(50.0) + self.ui.dsb_smallRadius.setValue(40.0) + self.ui.dsb_bigHeight.setValue(80.0) + self.ui.dsb_smallHeight.setValue(80.0) def accept(self): self._wasOk = True QtGui.QDialog.accept(self) def getData(self): - r1 = self.ui.doubleSpinBox.value() - r2 = self.ui.doubleSpinBox_2.value() - h1 = self.ui.doubleSpinBox_3.value() - h2 = self.ui.doubleSpinBox_4.value() - thickness = self.ui.doubleSpinBox_5.value() + r1 = self.ui.dsb_bigRadius.value() + r2 = self.ui.dsb_smallRadius.value() + h1 = self.ui.dsb_bigHeight.value() + h2 = self.ui.dsb_smallHeight.value() + thickness = self.ui.dsb_solidThickness.value() return r1, r2, h1, h2, thickness diff --git a/src/Tools/t_shape/t_shape_dialog.ui b/src/Tools/t_shape/t_shape_dialog.ui index 8caa136b5..55a48232e 100644 --- a/src/Tools/t_shape/t_shape_dialog.ui +++ b/src/Tools/t_shape/t_shape_dialog.ui @@ -17,7 +17,17 @@ - + + + 5 + + + 100000.000000000000000 + + + 40.000000000000000 + + @@ -27,13 +37,43 @@ - + + + 5 + + + 1000000.000000000000000 + + + 80.000000000000000 + + - + + + 5 + + + 1000000.000000000000000 + + + 80.000000000000000 + + - + + + 5 + + + 100000.000000000000000 + + + 50.000000000000000 + + @@ -61,7 +101,7 @@ - + Build solid part @@ -75,7 +115,17 @@ - + + + 5 + + + 1000000.000000000000000 + + + 5.000000000000000 + + @@ -126,14 +176,14 @@ - checkBox + cb_buildSolid clicked(bool) label_5 setEnabled(bool) - 89 - 184 + 99 + 170 107 @@ -142,14 +192,14 @@ - checkBox + cb_buildSolid clicked(bool) - doubleSpinBox_5 + dsb_solidThickness setEnabled(bool) - 140 - 178 + 150 + 170 277 diff --git a/src/Tools/t_shape/t_shape_dialog_ui.py b/src/Tools/t_shape/t_shape_dialog_ui.py deleted file mode 100644 index b034e677a..000000000 --- a/src/Tools/t_shape/t_shape_dialog_ui.py +++ /dev/null @@ -1,103 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 't_shape_dialog.ui' -# -# Created: Tue Nov 4 16:52:09 2014 -# by: PyQt4 UI code generator 4.9.6 -# -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui - -try: - _fromUtf8 = QtCore.QString.fromUtf8 -except AttributeError: - def _fromUtf8(s): - return s - -try: - _encoding = QtGui.QApplication.UnicodeUTF8 - def _translate(context, text, disambig): - return QtGui.QApplication.translate(context, text, disambig, _encoding) -except AttributeError: - def _translate(context, text, disambig): - return QtGui.QApplication.translate(context, text, disambig) - -class Ui_Dialog(object): - def setupUi(self, Dialog): - Dialog.setObjectName(_fromUtf8("Dialog")) - Dialog.resize(349, 283) - self.gridLayout_3 = QtGui.QGridLayout(Dialog) - self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3")) - self.gridLayout = QtGui.QGridLayout() - self.gridLayout.setObjectName(_fromUtf8("gridLayout")) - self.doubleSpinBox_2 = QtGui.QDoubleSpinBox(Dialog) - self.doubleSpinBox_2.setObjectName(_fromUtf8("doubleSpinBox_2")) - self.gridLayout.addWidget(self.doubleSpinBox_2, 2, 1, 1, 1) - self.label = QtGui.QLabel(Dialog) - self.label.setObjectName(_fromUtf8("label")) - self.gridLayout.addWidget(self.label, 0, 0, 1, 1) - self.doubleSpinBox_3 = QtGui.QDoubleSpinBox(Dialog) - self.doubleSpinBox_3.setObjectName(_fromUtf8("doubleSpinBox_3")) - self.gridLayout.addWidget(self.doubleSpinBox_3, 3, 1, 1, 1) - self.doubleSpinBox_4 = QtGui.QDoubleSpinBox(Dialog) - self.doubleSpinBox_4.setObjectName(_fromUtf8("doubleSpinBox_4")) - self.gridLayout.addWidget(self.doubleSpinBox_4, 4, 1, 1, 1) - self.doubleSpinBox = QtGui.QDoubleSpinBox(Dialog) - self.doubleSpinBox.setObjectName(_fromUtf8("doubleSpinBox")) - self.gridLayout.addWidget(self.doubleSpinBox, 0, 1, 1, 1) - self.label_3 = QtGui.QLabel(Dialog) - self.label_3.setObjectName(_fromUtf8("label_3")) - self.gridLayout.addWidget(self.label_3, 3, 0, 1, 1) - self.label_2 = QtGui.QLabel(Dialog) - self.label_2.setObjectName(_fromUtf8("label_2")) - self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1) - self.label_4 = QtGui.QLabel(Dialog) - self.label_4.setObjectName(_fromUtf8("label_4")) - self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1) - self.gridLayout_3.addLayout(self.gridLayout, 0, 0, 1, 1) - self.gridLayout_2 = QtGui.QGridLayout() - self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) - self.checkBox = QtGui.QCheckBox(Dialog) - self.checkBox.setObjectName(_fromUtf8("checkBox")) - self.gridLayout_2.addWidget(self.checkBox, 0, 0, 1, 1) - self.label_5 = QtGui.QLabel(Dialog) - self.label_5.setObjectName(_fromUtf8("label_5")) - self.gridLayout_2.addWidget(self.label_5, 1, 0, 1, 1) - self.doubleSpinBox_5 = QtGui.QDoubleSpinBox(Dialog) - self.doubleSpinBox_5.setObjectName(_fromUtf8("doubleSpinBox_5")) - self.gridLayout_2.addWidget(self.doubleSpinBox_5, 1, 1, 1, 1) - self.gridLayout_3.addLayout(self.gridLayout_2, 1, 0, 1, 1) - self.buttonBox = QtGui.QDialogButtonBox(Dialog) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) - self.buttonBox.setObjectName(_fromUtf8("buttonBox")) - self.gridLayout_3.addWidget(self.buttonBox, 2, 0, 1, 1) - - self.retranslateUi(Dialog) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject) - QtCore.QObject.connect(self.checkBox, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.label_5.setEnabled) - QtCore.QObject.connect(self.checkBox, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.doubleSpinBox_5.setEnabled) - QtCore.QMetaObject.connectSlotsByName(Dialog) - - def retranslateUi(self, Dialog): - Dialog.setWindowTitle(_translate("Dialog", "Dialog", None)) - self.label.setText(_translate("Dialog", "Big pipe radius", None)) - self.label_3.setText(_translate("Dialog", "Big pipe height", None)) - self.label_2.setText(_translate("Dialog", "Small pipe radius", None)) - self.label_4.setText(_translate("Dialog", "Small pipe height", None)) - self.checkBox.setText(_translate("Dialog", "Build solid part", None)) - self.label_5.setText(_translate("Dialog", "Solid thickness", None)) - -if __name__ == "__main__": - import sys - app = QtGui.QApplication(sys.argv) - Dialog = QtGui.QDialog() - ui = Ui_Dialog() - ui.setupUi(Dialog) - Dialog.show() - sys.exit(app.exec_()) - - - From 4fbce42ee33ccf1fb9241e7ed63a87b41b572fa1 Mon Sep 17 00:00:00 2001 From: Paul RASCLE Date: Fri, 8 Jan 2016 18:05:40 +0100 Subject: [PATCH 32/63] debug dialog, print commented --- src/Tools/t_shape/t_shape_builder.py | 22 +++++++++++++--------- src/Tools/t_shape/t_shape_dialog.py | 4 +++- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/Tools/t_shape/t_shape_builder.py b/src/Tools/t_shape/t_shape_builder.py index 3082dc849..7e9ab3e34 100644 --- a/src/Tools/t_shape/t_shape_builder.py +++ b/src/Tools/t_shape/t_shape_builder.py @@ -8,13 +8,15 @@ from salome.geom import geomBuilder import math import SALOMEDS +geompy = None + def demidisk(study, r1, a1, roty=0, solid_thickness=0): if solid_thickness < 1e-7: with_solid = False else: with_solid = True - geompy = geomBuilder.New(study) + #geompy = geomBuilder.New(study) O = geompy.MakeVertex(0, 0, 0) OX = geompy.MakeVectorDXDYDZ(1, 0, 0) @@ -81,7 +83,7 @@ def demidisk(study, r1, a1, roty=0, solid_thickness=0): return v, l, arc1, part1 def pointsProjetes(study, vref, face): - geompy = geomBuilder.New(study) + #geompy = geomBuilder.New(study) vface = geompy.ExtractShapes(face, geompy.ShapeType["VERTEX"], True) vord = range(len(vref)) plan = geompy.MakePlaneThreePnt(vref[0], vref[1], vref[-1], 10000) @@ -94,7 +96,7 @@ def pointsProjetes(study, vref, face): return vord def arcsProjetes(study, vf, face): - geompy = geomBuilder.New(study) + #geompy = geomBuilder.New(study) lface = geompy.ExtractShapes(face, geompy.ShapeType["EDGE"], True) lord = range(3) ends = [vf[1], vf[6], vf[7], vf[3]] @@ -104,7 +106,7 @@ def arcsProjetes(study, vf, face): if (((geompy.MinDistance(pts[0], ends[i]) < 0.001) and (geompy.MinDistance(pts[1], ends[i+1]) < 0.001)) or ((geompy.MinDistance(pts[1], ends[i]) < 0.001) and (geompy.MinDistance(pts[0], ends[i+1]) < 0.001))): lord[i] = lf - print "arc_%d OK"%i + #print "arc_%d OK"%i break pass return lord @@ -117,6 +119,7 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): else: with_solid = True + global geompy geompy = geomBuilder.New(study) O = geompy.MakeVertex(0, 0, 0) @@ -205,7 +208,7 @@ def jonction(study, r1, r2, h1, h2, a1): """ Builds the jonction faces and returns what is needed to build the whole pipe """ - geompy = geomBuilder.New(study) + #geompy = geomBuilder.New(study) O = geompy.MakeVertex(0, 0, 0) OX = geompy.MakeVectorDXDYDZ(1, 0, 0) @@ -232,6 +235,7 @@ def jonction(study, r1, r2, h1, h2, a1): sect45 = geompy.MakeCommonList([demicyl1, planr], True) sect90 = geompy.MakeCommonList([demicyl2, arcextru], True) + #geompy.addToStudy(sect90, "sect90") # --- liste ordonnée des points projetés sur les deux sections @@ -248,7 +252,7 @@ def jonction(study, r1, r2, h1, h2, a1): dz = -r2/2.0 for i in (0, 2, 4, 5): vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz, True) - geompy.addToStudyInFather(sect90, vord90[i], 'vm%d'%i) + #geompy.addToStudyInFather(sect90, vord90[i], 'vm%d'%i) # --- création des deux arêtes curvilignes sur l'enveloppe cylindrique du cylindre principal, à la jonction @@ -259,7 +263,7 @@ def jonction(study, r1, r2, h1, h2, a1): lipts = ((6, 6, 4), (7, 7, 5)) for i, ipts in enumerate(lipts): - print i, ipts + #print i, ipts p0 = vord90[ipts[0]] p1 = vord45[ipts[1]] p2 = vord45[ipts[2]] @@ -267,7 +271,7 @@ def jonction(study, r1, r2, h1, h2, a1): #geompy.addToStudy(plan, "plan%d"%i) section = geompy.MakeSection(plan, arcextru, True) secpart = geompy.MakePartition([section], [sect45, sect90], [], [], geompy.ShapeType["EDGE"], 0, [], 0, True) - geompy.addToStudy(secpart, "secpart%d"%i) + #geompy.addToStudy(secpart, "secpart%d"%i) lsec = geompy.ExtractShapes(secpart, geompy.ShapeType["EDGE"], True) for l in lsec: @@ -275,7 +279,7 @@ def jonction(study, r1, r2, h1, h2, a1): if (((geompy.MinDistance(pts[0], p0) < 0.001) and (geompy.MinDistance(pts[1], p1) < 0.001)) or ((geompy.MinDistance(pts[1], p0) < 0.001) and (geompy.MinDistance(pts[0], p1) < 0.001))): curv[i+2] =l - print "curv_%d OK"%i + #print "curv_%d OK"%i break # --- creation des arêtes droites manquantes, des faces et volumes pour les quatre volumes de la jonction diff --git a/src/Tools/t_shape/t_shape_dialog.py b/src/Tools/t_shape/t_shape_dialog.py index 9fb4f9b28..c385efd0c 100644 --- a/src/Tools/t_shape/t_shape_dialog.py +++ b/src/Tools/t_shape/t_shape_dialog.py @@ -50,7 +50,9 @@ class TShapeDialog(QtGui.QDialog): r2 = self.ui.dsb_smallRadius.value() h1 = self.ui.dsb_bigHeight.value() h2 = self.ui.dsb_smallHeight.value() - thickness = self.ui.dsb_solidThickness.value() + thickness = 0.0 + if self.ui.cb_buildSolid.isChecked(): + thickness = self.ui.dsb_solidThickness.value() return r1, r2, h1, h2, thickness From bb7dc217165025db02ea2cd7d0b4b60d6583ea40 Mon Sep 17 00:00:00 2001 From: Paul RASCLE Date: Sun, 10 Jan 2016 18:23:44 +0100 Subject: [PATCH 33/63] t_shape available in salome.geom Pythonpath, test as a function --- src/Tools/geom_plugins.py | 4 ++-- src/Tools/t_shape/CMakeLists.txt | 4 ++-- src/Tools/t_shape/t_shape_builder.py | 21 ++++++++++++++------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Tools/geom_plugins.py b/src/Tools/geom_plugins.py index a1f6ab394..d9ed81f41 100644 --- a/src/Tools/geom_plugins.py +++ b/src/Tools/geom_plugins.py @@ -22,8 +22,8 @@ import salome_pluginsmanager def t_shape_fluid(context): - from t_shape import t_shape_builder - from t_shape import t_shape_dialog + from salome.geom.t_shape import t_shape_builder + from salome.geom.t_shape import t_shape_dialog import xalome from PyQt4.QtGui import QMessageBox activeStudy = context.study diff --git a/src/Tools/t_shape/CMakeLists.txt b/src/Tools/t_shape/CMakeLists.txt index 4701fc26d..98f580077 100644 --- a/src/Tools/t_shape/CMakeLists.txt +++ b/src/Tools/t_shape/CMakeLists.txt @@ -40,5 +40,5 @@ PYQT4_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) # --- rules --- -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_GEOM_INSTALL_PLUGINS}/t_shape) -SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_GEOM_INSTALL_PLUGINS}/t_shape) \ No newline at end of file +SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/geom/t_shape) +SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/geom/t_shape) \ No newline at end of file diff --git a/src/Tools/t_shape/t_shape_builder.py b/src/Tools/t_shape/t_shape_builder.py index 7e9ab3e34..d4230cf23 100644 --- a/src/Tools/t_shape/t_shape_builder.py +++ b/src/Tools/t_shape/t_shape_builder.py @@ -327,16 +327,23 @@ def jonction(study, r1, r2, h1, h2, a1): return faci, sect45, arc1, l1, lord90, lord45, edges, arcextru -if __name__=="__main__": +def test_t_shape_builder(): """For testing purpose""" salome.salome_init() theStudy = salome.myStudy geompy = geomBuilder.New(theStudy) - for r1 in [1, 100, 10000]: - for r2 in [0.75*r1, 0.3*r1, 0.1*r1]: - for thickness in [(r1-r2)/10.0, (r1-r2) /2.0, 0.75*(r1-r2)]: - h1 = r1 * 1.5 + for r1 in [1., 100.]: + for r2 in [0.9*r1, 0.5*r1, 0.1*r1, 0.05*r1]: + for thickness in [r1/100., r1/10., r1/2.]: + print r1, r2, thickness + h1 = r1 * 2.0 h2 = h1 - res = build_shape(theStudy, r1, r2, h1, h2, thickness) - geompy.addToStudy(res, "res_%f_%f_%f"%(r1,r2, thickness)) + try: + res = build_shape(theStudy, r1, r2, h1, h2, thickness) + geompy.addToStudy(res, "res_%f_%f_%f"%(r1,r2, thickness)) + except: + print "problem with res_%f_%f_%f"%(r1,r2, thickness) +if __name__=="__main__": + """For testing purpose""" + test_t_shape_builder() From 8fb7cb1a010fc361256db5905c6bcd1623244041 Mon Sep 17 00:00:00 2001 From: Paul RASCLE Date: Sun, 10 Jan 2016 23:13:10 +0100 Subject: [PATCH 34/63] progress bar on t_shape_builder plugin --- src/Tools/CMakeLists.txt | 2 +- src/Tools/geom_plugins.py | 7 +++-- src/Tools/t_shape/CMakeLists.txt | 1 + src/Tools/t_shape/t_shape_builder.py | 33 ++++++++++++++++++++--- src/Tools/t_shape/t_shape_progress.py | 39 +++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 src/Tools/t_shape/t_shape_progress.py diff --git a/src/Tools/CMakeLists.txt b/src/Tools/CMakeLists.txt index 435c5fdae..741357566 100644 --- a/src/Tools/CMakeLists.txt +++ b/src/Tools/CMakeLists.txt @@ -21,7 +21,7 @@ ADD_SUBDIRECTORY(t_shape) # scripts / static SET(plugin_SCRIPTS - geom_plugins.py + geom_plugins.py ) # --- rules --- diff --git a/src/Tools/geom_plugins.py b/src/Tools/geom_plugins.py index d9ed81f41..395961595 100644 --- a/src/Tools/geom_plugins.py +++ b/src/Tools/geom_plugins.py @@ -22,8 +22,9 @@ import salome_pluginsmanager def t_shape_fluid(context): - from salome.geom.t_shape import t_shape_builder + #from salome.geom.t_shape import t_shape_builder from salome.geom.t_shape import t_shape_dialog + from salome.geom.t_shape import t_shape_progress import xalome from PyQt4.QtGui import QMessageBox activeStudy = context.study @@ -37,7 +38,9 @@ def t_shape_fluid(context): if dialog.wasOk(): r1, r2, h1, h2, thickness = dialog.getData() #QMessageBox.about(None, "Building in progress", "building shape, please be patient") - shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2, thickness) + #shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2, thickness) + shapeBuilder = t_shape_progress.t_shape_progress() + shape = shapeBuilder.run(activeStudy, r1, r2, h1, h2, thickness) entry = xalome.addToStudy(activeStudy, shape, "T_shape_fluid" ) xalome.displayShape(entry) #if dialog.wasOk(): diff --git a/src/Tools/t_shape/CMakeLists.txt b/src/Tools/t_shape/CMakeLists.txt index 98f580077..e3fb538c3 100644 --- a/src/Tools/t_shape/CMakeLists.txt +++ b/src/Tools/t_shape/CMakeLists.txt @@ -27,6 +27,7 @@ SET(plugin_SCRIPTS t_shape_builder.py t_shape_dialog.py t_shape_dialog.ui + t_shape_progress.py ) # uic files / to be processed by pyuic diff --git a/src/Tools/t_shape/t_shape_builder.py b/src/Tools/t_shape/t_shape_builder.py index d4230cf23..872899ae5 100644 --- a/src/Tools/t_shape/t_shape_builder.py +++ b/src/Tools/t_shape/t_shape_builder.py @@ -111,7 +111,7 @@ def arcsProjetes(study, vf, face): pass return lord -def build_shape(study, r1, r2, h1, h2, solid_thickness=0): +def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): """ Builds the final shape """ if solid_thickness < 1e-7: @@ -136,6 +136,9 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): # --- Creation of the jonction faces [faci, sect45, arc1, l1, lord90, lord45, edges, arcextru] = jonction(study, r1, r2,\ h1, h2, a1) + if progressBar is not None: + progressBar.addSteps(1) + if with_solid: # The same code is executed again with different external radiuses in order # to get the needed faces and edges to build the solid layer of the pipe @@ -150,11 +153,17 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): for i,l in enumerate(lord45): faces_jonction_ext.append(geompy.MakeQuad2Edges(lord45[i],lord45_ext[i])) + if progressBar is not None: + progressBar.addSteps(1) + # --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres if with_solid: sect45 = geompy.MakeCompound([sect45]+faces_jonction_ext[-3:]) sect45 = geompy.MakeGlueEdges(sect45, 1e-7) + if progressBar is not None: + progressBar.addSteps(1) + extru1 = geompy.MakePrismVecH(sect45, OX, h1+10) faces_coupe = faci[5:] @@ -163,6 +172,9 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): base2 = geompy.MakePartition(faces_coupe, [], [], [], geompy.ShapeType["FACE"], 0, [], 0, True) extru2 = geompy.MakePrismVecH(base2, OZ, h2) + if progressBar is not None: + progressBar.addSteps(1) + # --- partition et coupe if with_solid: @@ -171,24 +183,36 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): demiDisque = geompy.MakeFaceWires([arc1, l1[0]], 1) demiCylindre = geompy.MakePrismVecH(demiDisque, OX, h1) + if progressBar is not None: + progressBar.addSteps(1) + box = geompy.MakeBox(0, -2*(r1+h1), -2*(r1+h1), 2*(r1+h1), 2*(r1+h1), 2*(r1+h1)) rot = geompy.MakeRotation(box, OY, 45*math.pi/180.0) # NOTE: The following Cut takes almost half of the total execution time garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True) + if progressBar is not None: + progressBar.addSteps(10) + faces_coupe = faci[:5] if with_solid: faces_coupe.extend(faces_jonction_ext[-7:]) raccord = geompy.MakePartition([garder], faces_coupe + [arcextru], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True) assemblage = geompy.MakeCompound([raccord, extru1, extru2]) assemblage = geompy.MakeGlueFaces(assemblage, 1e-7) - + + if progressBar is not None: + progressBar.addSteps(2) + box = geompy.MakeBox(-1, -(r1+r2+2*solid_thickness), -1, h1, r1+r2+2*solid_thickness, h2) # NOTE: This operation takes about 1/4 of the total execution time final = geompy.MakeCommonList([box, assemblage], True) + if progressBar is not None: + progressBar.addSteps(5) + # --- Partie inférieure v3, l3, arc3, part3 = demidisk(study, r1, a1, 180.0, solid_thickness) @@ -200,7 +224,10 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0): plane = geompy.MakePlane(O,OX,2000) compound_mirrored = geompy.MakeMirrorByPlane(compound, plane) final = geompy.MakeCompound([compound, compound_mirrored]) - + + if progressBar is not None: + progressBar.addSteps(1) + return final diff --git a/src/Tools/t_shape/t_shape_progress.py b/src/Tools/t_shape/t_shape_progress.py new file mode 100644 index 000000000..cc4533b16 --- /dev/null +++ b/src/Tools/t_shape/t_shape_progress.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2010-2014 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Renaud Nédélec (OpenCascade S.A.S) + +from salome.geom.t_shape import t_shape_builder +from PyQt4.QtGui import QProgressDialog + +class t_shape_progress(QProgressDialog): + _totSteps = 0 + _nmaxSteps = 20 + + def __init__(self): + QProgressDialog.__init__(self, "t_shape fluid build", "stop", 0, self._nmaxSteps) + + def run(self, activeStudy, r1, r2, h1, h2, thickness): + shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2, thickness, self) + self.setValue(self._nmaxSteps) + return shape + + def addSteps(self, nbSteps): + self._totSteps += nbSteps + self.setValue(self._totSteps) From d77224c91c27948bda7bb6bcaf8b641210e2f2d6 Mon Sep 17 00:00:00 2001 From: Paul RASCLE Date: Mon, 11 Jan 2016 10:30:40 +0100 Subject: [PATCH 35/63] adjust progress bar on t_shape_builder plugin --- src/Tools/t_shape/t_shape_builder.py | 26 ++++++++++++++++++++------ src/Tools/t_shape/t_shape_progress.py | 8 +++++--- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/Tools/t_shape/t_shape_builder.py b/src/Tools/t_shape/t_shape_builder.py index 872899ae5..72ab22bd2 100644 --- a/src/Tools/t_shape/t_shape_builder.py +++ b/src/Tools/t_shape/t_shape_builder.py @@ -7,6 +7,7 @@ import GEOM from salome.geom import geomBuilder import math import SALOMEDS +import time geompy = None @@ -113,7 +114,11 @@ def arcsProjetes(study, vf, face): def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): """ Builds the final shape """ - + + if progressBar is not None: + time0 = time.time() + print time.time() -time0 + if solid_thickness < 1e-7: with_solid = False else: @@ -137,7 +142,8 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): [faci, sect45, arc1, l1, lord90, lord45, edges, arcextru] = jonction(study, r1, r2,\ h1, h2, a1) if progressBar is not None: - progressBar.addSteps(1) + progressBar.addSteps(2) + print time.time() -time0 if with_solid: # The same code is executed again with different external radiuses in order @@ -154,7 +160,8 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): faces_jonction_ext.append(geompy.MakeQuad2Edges(lord45[i],lord45_ext[i])) if progressBar is not None: - progressBar.addSteps(1) + progressBar.addSteps(4) + print time.time() -time0 # --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres if with_solid: @@ -163,6 +170,7 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): if progressBar is not None: progressBar.addSteps(1) + print time.time() -time0 extru1 = geompy.MakePrismVecH(sect45, OX, h1+10) @@ -174,6 +182,7 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): if progressBar is not None: progressBar.addSteps(1) + print time.time() -time0 # --- partition et coupe @@ -185,6 +194,7 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): if progressBar is not None: progressBar.addSteps(1) + print time.time() -time0 box = geompy.MakeBox(0, -2*(r1+h1), -2*(r1+h1), 2*(r1+h1), 2*(r1+h1), 2*(r1+h1)) rot = geompy.MakeRotation(box, OY, 45*math.pi/180.0) @@ -193,8 +203,9 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True) if progressBar is not None: - progressBar.addSteps(10) - + progressBar.addSteps(9) + print time.time() -time0 + faces_coupe = faci[:5] if with_solid: faces_coupe.extend(faces_jonction_ext[-7:]) @@ -203,7 +214,8 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): assemblage = geompy.MakeGlueFaces(assemblage, 1e-7) if progressBar is not None: - progressBar.addSteps(2) + progressBar.addSteps(3) + print time.time() -time0 box = geompy.MakeBox(-1, -(r1+r2+2*solid_thickness), -1, h1, r1+r2+2*solid_thickness, h2) @@ -212,6 +224,7 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): if progressBar is not None: progressBar.addSteps(5) + print time.time() -time0 # --- Partie inférieure @@ -227,6 +240,7 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): if progressBar is not None: progressBar.addSteps(1) + print time.time() -time0 return final diff --git a/src/Tools/t_shape/t_shape_progress.py b/src/Tools/t_shape/t_shape_progress.py index cc4533b16..38f804502 100644 --- a/src/Tools/t_shape/t_shape_progress.py +++ b/src/Tools/t_shape/t_shape_progress.py @@ -21,13 +21,15 @@ from salome.geom.t_shape import t_shape_builder from PyQt4.QtGui import QProgressDialog +from PyQt4 import QtCore class t_shape_progress(QProgressDialog): _totSteps = 0 - _nmaxSteps = 20 + _nmaxSteps = 27 - def __init__(self): - QProgressDialog.__init__(self, "t_shape fluid build", "stop", 0, self._nmaxSteps) + def __init__(self, parent=None): + QProgressDialog.__init__(self, "t_shape fluid build", "stop", 0, self._nmaxSteps, parent, QtCore.Qt.Tool) + self.show() def run(self, activeStudy, r1, r2, h1, h2, thickness): shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2, thickness, self) From de5a77605cadc21fbee90ff66441f509d80eedd5 Mon Sep 17 00:00:00 2001 From: "Maintenance team (INV)" Date: Thu, 14 Jan 2016 16:13:07 +0300 Subject: [PATCH 36/63] RNV : Build T-Shape plugin without GUI --- src/Tools/CMakeLists.txt | 14 ++++++----- src/Tools/t_shape/CMakeLists.txt | 40 ++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/Tools/CMakeLists.txt b/src/Tools/CMakeLists.txt index 741357566..57f854fe7 100644 --- a/src/Tools/CMakeLists.txt +++ b/src/Tools/CMakeLists.txt @@ -19,11 +19,13 @@ ADD_SUBDIRECTORY(t_shape) -# scripts / static -SET(plugin_SCRIPTS - geom_plugins.py -) -# --- rules --- +IF(SALOME_BUILD_GUI) + # scripts / static + SET(plugin_SCRIPTS + geom_plugins.py + ) -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_GEOM_INSTALL_PLUGINS}) + # --- rules --- + SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_GEOM_INSTALL_PLUGINS}) +ENDIF() diff --git a/src/Tools/t_shape/CMakeLists.txt b/src/Tools/t_shape/CMakeLists.txt index e3fb538c3..15394fdb2 100644 --- a/src/Tools/t_shape/CMakeLists.txt +++ b/src/Tools/t_shape/CMakeLists.txt @@ -16,30 +16,40 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # - -INCLUDE(UsePyQt4) +IF(SALOME_BUILD_GUI) + INCLUDE(UsePyQt4) +ENDIF() # --- scripts --- -# scripts / static -SET(plugin_SCRIPTS +# base scripts +SET(base_SCRIPTS __init__.py t_shape_builder.py - t_shape_dialog.py - t_shape_dialog.ui - t_shape_progress.py ) -# uic files / to be processed by pyuic -SET(_pyuic_files - t_shape_dialog.ui -) +IF(SALOME_BUILD_GUI) + # gui scripts + SET(gui_SCRIPTS + t_shape_dialog.py + t_shape_dialog.ui + t_shape_progress.py + ) -# scripts / pyuic wrappings -PYQT4_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) + # uic files / to be processed by pyuic + SET(_pyuic_files + t_shape_dialog.ui + ) + # scripts / pyuic wrappings + PYQT4_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) +ENDIF() # --- rules --- -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/geom/t_shape) -SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/geom/t_shape) \ No newline at end of file +SALOME_INSTALL_SCRIPTS("${base_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/geom/t_shape) + +IF(SALOME_BUILD_GUI) + SALOME_INSTALL_SCRIPTS("${gui_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/geom/t_shape) + SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/geom/t_shape) +ENDIF() \ No newline at end of file From e44e43fed44829929519370c456ca79f1d8c3f41 Mon Sep 17 00:00:00 2001 From: Paul RASCLE Date: Thu, 14 Jan 2016 16:14:39 +0100 Subject: [PATCH 37/63] t_shape_fluid: glue faces --- src/Tools/t_shape/t_shape_builder.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Tools/t_shape/t_shape_builder.py b/src/Tools/t_shape/t_shape_builder.py index 72ab22bd2..0cff46b98 100644 --- a/src/Tools/t_shape/t_shape_builder.py +++ b/src/Tools/t_shape/t_shape_builder.py @@ -236,7 +236,8 @@ def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ): compound = geompy.MakeCompound([final, extru3]) plane = geompy.MakePlane(O,OX,2000) compound_mirrored = geompy.MakeMirrorByPlane(compound, plane) - final = geompy.MakeCompound([compound, compound_mirrored]) + compound_total = geompy.MakeCompound([compound, compound_mirrored]) + final = geompy.MakeGlueFaces(compound_total, 1e-07) if progressBar is not None: progressBar.addSteps(1) From 845487b15668b2d333b5065cf155946be5368c31 Mon Sep 17 00:00:00 2001 From: mpa Date: Mon, 18 Jan 2016 11:00:10 +0300 Subject: [PATCH 38/63] 0023210: [CEA 1681] Regression with the function GetInPlaceByHistory --- idl/GEOM_Gen.idl | 6 ++-- src/GEOM_SWIG/geomBuilder.py | 12 ++++--- src/XAOPlugin/XAOPlugin_IOperations.cxx | 37 ++++++++++++---------- src/XAOPlugin/XAOPlugin_IOperations.hxx | 42 ++++++++++++------------- 4 files changed, 54 insertions(+), 43 deletions(-) diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 830fcc398..1e572a79f 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -2654,7 +2654,8 @@ module GEOM * coincident with \a theShapeWhat or could be a part of it. * \param theShapeWhere Shape to find sub-shapes of. * \param theShapeWhat Shape, specifying what to find. - * \return Group of all found sub-shapes or a single found sub-shape. + * \return Compound which includes all found sub-shapes if they have different types; + * or group of all found shapes of the equal type; or a single found sub-shape. */ GEOM_Object GetInPlace (in GEOM_Object theShapeWhere, in GEOM_Object theShapeWhat); @@ -2677,7 +2678,8 @@ module GEOM * * \param theShapeWhere Shape to find sub-shapes of. * \param theShapeWhat Shape, specifying what to find. - * \return Group of all found sub-shapes or a single found sub-shape. + * \return Compound which includes all found sub-shapes if they have different types; + * or group of all found shapes of the equal type; or a single found sub-shape. */ GEOM_Object GetInPlaceByHistory (in GEOM_Object theShapeWhere, in GEOM_Object theShapeWhat); diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 0f90ef502..297b3a18a 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -5866,7 +5866,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # for result publication in the study. Otherwise, if automatic # publication is switched on, default value is used for result name. # - # @return Group of all found sub-shapes or a single found sub-shape. + # @return Compound which includes all found sub-shapes if they have different types; + # or group of all found shapes of the equal type; or a single found sub-shape. # # @note This function has a restriction on argument shapes. # If \a theShapeWhere has curved parts with significantly @@ -5891,7 +5892,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): publication is switched on, default value is used for result name. Returns: - Group of all found sub-shapes or a single found sub-shape. + Compound which includes all found sub-shapes if they have different types; + or group of all found shapes of the equal type; or a single found sub-shape. Note: @@ -5927,7 +5929,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # for result publication in the study. Otherwise, if automatic # publication is switched on, default value is used for result name. # - # @return Group of all found sub-shapes or a single found sub-shape. + # @return Compound which includes all found sub-shapes if they have different types; + # or group of all found shapes of the equal type; or a single found sub-shape. # # @ref swig_GetInPlace "Example" @ManageTransactions("ShapesOp") @@ -5948,7 +5951,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): publication is switched on, default value is used for result name. Returns: - Group of all found sub-shapes or a single found sub-shape. + Compound which includes all found sub-shapes if they have different types; + or group of all found shapes of the equal type; or a single found sub-shape. """ # Example: see GEOM_TestOthers.py anObj = self.ShapesOp.GetInPlaceByHistory(theShapeWhere, theShapeWhat) diff --git a/src/XAOPlugin/XAOPlugin_IOperations.cxx b/src/XAOPlugin/XAOPlugin_IOperations.cxx index d8c886274..a6f094194 100644 --- a/src/XAOPlugin/XAOPlugin_IOperations.cxx +++ b/src/XAOPlugin/XAOPlugin_IOperations.cxx @@ -113,15 +113,19 @@ XAOPlugin_IOperations::~XAOPlugin_IOperations() MESSAGE( "XAOPlugin_IOperations::~XAOPlugin_IOperations" ); } -void XAOPlugin_IOperations::exportGroups( std::list groupList, - XAO::Xao* xaoObject, - XAO::BrepGeometry* geometry ) +bool XAOPlugin_IOperations::exportGroups( std::list groupList, + XAO::Xao* xaoObject, + XAO::BrepGeometry* geometry ) { // add the groups std::list::iterator groupIterator = groupList.begin(); while (groupIterator != groupList.end()) { Handle(GEOM_Object) currGroup = (*groupIterator++); + if (currGroup->GetType() != GEOM_GROUP) { + SetErrorCode("Error when export groups: you could perform this operation only with group."); + return false; + } Handle(TColStd_HArray1OfInteger) groupIds = myGroupOperations->GetObjects(currGroup); TopAbs_ShapeEnum shapeGroup = myGroupOperations->GetType(currGroup); @@ -164,11 +168,12 @@ void XAOPlugin_IOperations::exportGroups( std::list groupLi break; } } + return true; } void XAOPlugin_IOperations::exportFields( std::list fieldList, - XAO::Xao* xaoObject, - XAO::BrepGeometry* geometry ) + XAO::Xao* xaoObject, + XAO::BrepGeometry* geometry ) { std::list::iterator fieldIterator = fieldList.begin(); while (fieldIterator != fieldList.end()) @@ -301,10 +306,10 @@ void XAOPlugin_IOperations::exportSubshapes( const Handle(GEOM_Object)& shape, X */ //============================================================================= bool XAOPlugin_IOperations::ExportXAO( Handle(GEOM_Object) shape, - std::list groupList, - std::list fieldList, - const char* author, - const char* fileName ) + std::list groupList, + std::list fieldList, + const char* author, + const char* fileName ) { SetErrorCode(KO); @@ -337,7 +342,7 @@ bool XAOPlugin_IOperations::ExportXAO( Handle(GEOM_Object) shape, exportSubshapes(shape, geometry); xaoObject->setGeometry(geometry); - exportGroups(groupList, xaoObject, geometry); + if (!exportGroups(groupList, xaoObject, geometry)) return false; exportFields(fieldList, xaoObject, geometry); // export the XAO to the file @@ -380,8 +385,8 @@ bool XAOPlugin_IOperations::ExportXAO( Handle(GEOM_Object) shape, } void XAOPlugin_IOperations::importSubShapes( XAO::Geometry* xaoGeometry, - Handle(GEOM_Function) function, int shapeType, int dim, - Handle(TColStd_HSequenceOfTransient)& subShapeList ) + Handle(GEOM_Function) function, int shapeType, int dim, + Handle(TColStd_HSequenceOfTransient)& subShapeList ) { Handle(GEOM_Object) subShape; Handle(GEOM_Function) aFunction; @@ -433,10 +438,10 @@ void XAOPlugin_IOperations::importSubShapes( XAO::Geometry* xaoGeometry, */ //============================================================================= bool XAOPlugin_IOperations::ImportXAO( const char* fileName, - Handle(GEOM_Object)& shape, - Handle(TColStd_HSequenceOfTransient)& subShapes, - Handle(TColStd_HSequenceOfTransient)& groups, - Handle(TColStd_HSequenceOfTransient)& fields ) + Handle(GEOM_Object)& shape, + Handle(TColStd_HSequenceOfTransient)& subShapes, + Handle(TColStd_HSequenceOfTransient)& groups, + Handle(TColStd_HSequenceOfTransient)& fields ) { SetErrorCode(KO); diff --git a/src/XAOPlugin/XAOPlugin_IOperations.hxx b/src/XAOPlugin/XAOPlugin_IOperations.hxx index 869e3a1c2..2b477442a 100644 --- a/src/XAOPlugin/XAOPlugin_IOperations.hxx +++ b/src/XAOPlugin/XAOPlugin_IOperations.hxx @@ -44,31 +44,31 @@ public: ~XAOPlugin_IOperations(); bool ExportXAO( Handle(GEOM_Object) shape, - std::list groupList, - std::list fieldList, - const char* author, - const char* fileName ); + std::list groupList, + std::list fieldList, + const char* author, + const char* fileName ); bool ImportXAO( const char* fileName, - Handle(GEOM_Object)& shape, - Handle(TColStd_HSequenceOfTransient)& subShapes, - Handle(TColStd_HSequenceOfTransient)& groups, - Handle(TColStd_HSequenceOfTransient)& fields ); + Handle(GEOM_Object)& shape, + Handle(TColStd_HSequenceOfTransient)& subShapes, + Handle(TColStd_HSequenceOfTransient)& groups, + Handle(TColStd_HSequenceOfTransient)& fields ); private: - void importSubShapes( XAO::Geometry* xaoGeometry, - Handle(GEOM_Function) function, - int shapeType, - int dim, - Handle(TColStd_HSequenceOfTransient)& subshapeList ); - void exportSubshapes( const Handle(GEOM_Object)& shape, - XAO::BrepGeometry* geometry ); - void exportFields( std::list fieldList, - XAO::Xao* xaoObject, - XAO::BrepGeometry* geometry ); - void exportGroups( std::list groupList, - XAO::Xao* xaoObject, - XAO::BrepGeometry* geometry ); + void importSubShapes( XAO::Geometry* xaoGeometry, + Handle(GEOM_Function) function, + int shapeType, + int dim, + Handle(TColStd_HSequenceOfTransient)& subshapeList ); + void exportSubshapes( const Handle(GEOM_Object)& shape, + XAO::BrepGeometry* geometry ); + void exportFields( std::list fieldList, + XAO::Xao* xaoObject, + XAO::BrepGeometry* geometry ); + bool exportGroups( std::list groupList, + XAO::Xao* xaoObject, + XAO::BrepGeometry* geometry ); }; #endif From 6013ddd73d559f081bf0a60273b192282ded75cc Mon Sep 17 00:00:00 2001 From: mpa Date: Mon, 18 Jan 2016 13:49:09 +0300 Subject: [PATCH 39/63] Adding of the necessary translations --- src/GEOMGUI/GEOM_msg_en.ts | 8 ++++++++ src/GEOMGUI/GEOM_msg_fr.ts | 8 ++++++++ src/GEOMGUI/GEOM_msg_ja.ts | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 5a094f303..7aef53a75 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -4960,10 +4960,18 @@ Please, select face, shell or solid and try again MEN_POP_SHOW_DEPENDENCY_TREE Show dependency tree + + STB_POP_SHOW_DEPENDENCY_TREE + Show dependency tree + MEN_POP_REDUCE_STUDY Reduce study + + STB_POP_REDUCE_STUDY + Reduce study + MEN_POP_SHOW_ALL_DIMENSIONS Show all dimensions diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 01acd20ca..a7111b94c 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -4952,10 +4952,18 @@ Choisissez une face, une coque ou un solide et essayez de nouveau MEN_POP_SHOW_DEPENDENCY_TREE Montrer l'arbre des dépendances + + STB_POP_SHOW_DEPENDENCY_TREE + Montrer l'arbre des dépendances + MEN_POP_REDUCE_STUDY Etude réduite + + STB_POP_REDUCE_STUDY + Etude réduite + MEN_POP_SHOW_ALL_DIMENSIONS Afficher les cotations diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index 0a55e444f..0e42dfe3d 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -4955,10 +4955,18 @@ MEN_POP_SHOW_DEPENDENCY_TREE 依存ツリーの表示 + + STB_POP_SHOW_DEPENDENCY_TREE + 依存ツリーの表示 + MEN_POP_REDUCE_STUDY スタディの削減 + + STB_POP_REDUCE_STUDY + スタディの削減 + MEN_POP_SHOW_ALL_DIMENSIONS すべての寸法を表示 From a4a4fee20cf2481d300bc74fe84c5d7b2c1e5851 Mon Sep 17 00:00:00 2001 From: skv Date: Thu, 28 Jan 2016 17:08:15 +0300 Subject: [PATCH 40/63] 0052919: Build shell with two brep files creates suspected result --- src/GEOMImpl/GEOMImpl_ShapeDriver.cxx | 216 ++++++++++++++++++++------ 1 file changed, 165 insertions(+), 51 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 8b585f83e..5072071be 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -73,6 +73,8 @@ #include #include +#include +#include #include #include @@ -161,6 +163,165 @@ namespace return result; } + + /** + * This function constructs a shell or a compound of shells from a set of faces and/or shells. + * + * @param theShapes is a set of faces and/or shells. + * @return a shell or a compound of shells. + */ + TopoDS_Shape makeShellFromFaces + (const Handle(TColStd_HSequenceOfTransient) &theShapes) + { + const Standard_Integer aNbShapes = theShapes->Length(); + Standard_Integer i; + TopTools_ListOfShape aListFaces; + TopTools_MapOfShape aMapFence; + BRep_Builder aBuilder; + + // Fill the list of unique faces + for (i = 1; i <= aNbShapes; ++i) { + // Function + const Handle(GEOM_Function) aRefShape = + Handle(GEOM_Function)::DownCast(theShapes->Value(i)); + + if (aRefShape.IsNull()) { + Standard_NullObject::Raise("Face for shell construction is null"); + } + + // Shape + const TopoDS_Shape aShape = aRefShape->GetValue(); + + if (aShape.IsNull()) { + Standard_NullObject::Raise("Face for shell construction is null"); + } + + // Shape type + const TopAbs_ShapeEnum aType = aShape.ShapeType(); + + if (aType == TopAbs_SHELL) { + // Get faces. + TopExp_Explorer anExp(aShape, TopAbs_FACE); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aFace = anExp.Current(); + + if (aMapFence.Add(aFace)) { + aListFaces.Append(aFace); + } + } + } else if (aType == TopAbs_FACE) { + // Append the face in the list + if (aMapFence.Add(aShape)) { + aListFaces.Append(aShape); + } + } else { + Standard_TypeMismatch::Raise + ("Shape for shell construction is neither a shell nor a face"); + } + } + + // Perform computation of shells. + TopTools_ListOfShape aListShells; + TopTools_ListIteratorOfListOfShape anIter; + + while (!aListFaces.IsEmpty()) { + // Perform sewing + BRepBuilderAPI_Sewing aSewing(Precision::Confusion()*10.0); + + for (anIter.Initialize(aListFaces); anIter.More(); anIter.Next()) { + aSewing.Add(anIter.Value()); + } + + aSewing.Perform(); + + // Fill list of shells. + const TopoDS_Shape &aSewed = aSewing.SewedShape(); + TopExp_Explorer anExp(aSewed, TopAbs_SHELL); + Standard_Boolean isNewShells = Standard_False; + + // Append shells + for (; anExp.More(); anExp.Next()) { + aListShells.Append(anExp.Current()); + isNewShells = Standard_True; + } + + // Append single faces. + anExp.Init(aSewed, TopAbs_FACE, TopAbs_SHELL); + + for (; anExp.More(); anExp.Next()) { + TopoDS_Shell aShell; + + aBuilder.MakeShell(aShell); + aBuilder.Add(aShell, anExp.Current()); + aListShells.Append(aShell); + isNewShells = Standard_True; + } + + if (!isNewShells) { + // There are no more shell can be obtained. Break the loop. + break; + } + + // Remove faces that are in the result from the list. + TopTools_IndexedMapOfShape aMapFaces; + + TopExp::MapShapes(aSewed, TopAbs_FACE, aMapFaces); + + // Add deleted faces to the map + const Standard_Integer aNbDelFaces = aSewing.NbDeletedFaces(); + + for (i = 1; i <= aNbDelFaces; ++i) { + aMapFaces.Add(aSewing.DeletedFace(i)); + } + + for (anIter.Initialize(aListFaces); anIter.More();) { + const TopoDS_Shape &aFace = anIter.Value(); + Standard_Boolean isFaceUsed = Standard_False; + + if (aMapFaces.Contains(aFace) || aSewing.IsModified(aFace)) { + // Remove face from the list. + aListFaces.Remove(anIter); + } else { + // Go to the next face. + anIter.Next(); + } + } + } + + // If there are faces not used in shells create a shell for each face. + for (anIter.Initialize(aListFaces); anIter.More(); anIter.Next()) { + TopoDS_Shell aShell; + + aBuilder.MakeShell(aShell); + aBuilder.Add(aShell, anIter.Value()); + aListShells.Append(aShell); + } + + // Construct the result that can be either a shell or a compound of shells + TopoDS_Shape aResult; + + if (!aListShells.IsEmpty()) { + if (aListShells.Extent() == 1) { + aResult = aListShells.First(); + } else { + // There are more then one shell. + TopoDS_Compound aCompound; + + aBuilder.MakeCompound(aCompound); + + for (anIter.Initialize(aListShells); anIter.More(); anIter.Next()) { + aBuilder.Add(aCompound, anIter.Value()); + } + + aResult = aCompound; + } + } + + return aResult; + } + + // End of namespace } //modified by NIZNHY-PKV Wed Dec 28 13:48:20 2011f @@ -432,60 +593,13 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const allowCompound = true; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); - unsigned int ind, nbshapes = aShapes->Length(); - // add faces - BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0); - for (ind = 1; ind <= nbshapes; ind++) { - Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); - TopoDS_Shape aShape_i = aRefShape->GetValue(); - if (aShape_i.IsNull()) { - Standard_NullObject::Raise("Face for shell construction is null"); - } - aSewing.Add(aShape_i); - } - - aSewing.Perform(); - - TopoDS_Shape sh = aSewing.SewedShape(); - - if (sh.ShapeType()==TopAbs_FACE && nbshapes==1) { - // case for creation of shell from one face - PAL12722 (skl 26.06.2006) - TopoDS_Shell ss; - B.MakeShell(ss); - B.Add(ss,sh); - aShape = ss; - } - else { - //TopExp_Explorer exp (aSewing.SewedShape(), TopAbs_SHELL); - TopExp_Explorer exp (sh, TopAbs_SHELL); - Standard_Integer ish = 0; - for (; exp.More(); exp.Next()) { - aShape = exp.Current(); - ish++; - } - - if (ish != 1) { - // try the case of one face (Mantis issue 0021809) - TopExp_Explorer expF (sh, TopAbs_FACE); - Standard_Integer ifa = 0; - for (; expF.More(); expF.Next()) { - aShape = expF.Current(); - ifa++; - } - - if (ifa == 1) { - TopoDS_Shell ss; - B.MakeShell(ss); - B.Add(ss,aShape); - aShape = ss; - } - else { - aShape = aSewing.SewedShape(); - } - } + if (aShapes.IsNull()) { + Standard_NullObject::Raise("Argument Shapes is null"); } + // Compute a shell or a compound of shells. + aShape = makeShellFromFaces(aShapes); } else if (aType == SOLID_SHELLS) { // result may be only a solid or a compound of solids From 78b2a5e0dad1c9a5b0085b8548adf55df319d59e Mon Sep 17 00:00:00 2001 From: skv Date: Wed, 3 Feb 2016 16:55:29 +0300 Subject: [PATCH 41/63] MakeShell: compound acceptance, update TUI documentation --- src/GEOMImpl/GEOMImpl_ShapeDriver.cxx | 78 +++++++++++++++++---------- src/GEOM_SWIG/geomBuilder.py | 4 +- 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 5072071be..46bcd193e 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -165,9 +165,55 @@ namespace } /** - * This function constructs a shell or a compound of shells from a set of faces and/or shells. + * This function adds faces from the input shape into the list of faces. If + * the input shape is a face, it is added itself. If it is a shell, its + * sub-shapes (faces) are added. If it is a compound, its sub-shapes + * (faces or shells) are added in the list. For null shapes and for other + * types of shapes an exception is thrown. * - * @param theShapes is a set of faces and/or shells. + * @param theShape the shape to be added. Either face or shell or a compound + * of faces and/or shells. + * @param theListFaces the list of faces that is modified on output. + * @param theMapFence the map that protects from adding the same faces in + * the list. + */ + void addFaces(const TopoDS_Shape &theShape, + TopTools_ListOfShape &theListFaces, + TopTools_MapOfShape &theMapFence) + { + if (theShape.IsNull()) { + Standard_NullObject::Raise("Face for shell construction is null"); + } + + // Append the shape is the mapFence + if (theMapFence.Add(theShape)) { + // Shape type + const TopAbs_ShapeEnum aType = theShape.ShapeType(); + + if (aType == TopAbs_FACE) { + theListFaces.Append(theShape); + } else if (aType == TopAbs_SHELL || aType == TopAbs_COMPOUND) { + TopoDS_Iterator anIter(theShape); + + for (; anIter.More(); anIter.Next()) { + // Add sub-shapes: faces for shell or faces/shells for compound. + const TopoDS_Shape &aSubShape = anIter.Value(); + + addFaces(aSubShape, theListFaces, theMapFence); + } + } else { + Standard_TypeMismatch::Raise + ("Shape for shell construction is neither a shell nor a face"); + } + } + } + + /** + * This function constructs a shell or a compound of shells + * from a set of faces and/or shells. + * + * @param theShapes is a set of faces, shells and/or + * compounds of faces/shells. * @return a shell or a compound of shells. */ TopoDS_Shape makeShellFromFaces @@ -192,33 +238,7 @@ namespace // Shape const TopoDS_Shape aShape = aRefShape->GetValue(); - if (aShape.IsNull()) { - Standard_NullObject::Raise("Face for shell construction is null"); - } - - // Shape type - const TopAbs_ShapeEnum aType = aShape.ShapeType(); - - if (aType == TopAbs_SHELL) { - // Get faces. - TopExp_Explorer anExp(aShape, TopAbs_FACE); - - for (; anExp.More(); anExp.Next()) { - const TopoDS_Shape &aFace = anExp.Current(); - - if (aMapFence.Add(aFace)) { - aListFaces.Append(aFace); - } - } - } else if (aType == TopAbs_FACE) { - // Append the face in the list - if (aMapFence.Add(aShape)) { - aListFaces.Append(aShape); - } - } else { - Standard_TypeMismatch::Raise - ("Shape for shell construction is neither a shell nor a face"); - } + addFaces(aShape, aListFaces, aMapFence); } // Perform computation of shells. diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 297b3a18a..379105b72 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -4834,8 +4834,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): self._autoPublish(anObj, theName, "face") return anObj - ## Create a shell from the set of faces and shells. - # @param theFacesAndShells List of faces and/or shells. + ## Create a shell from the set of faces, shells and/or compounds of faces. + # @param theFacesAndShells List of faces, shells and/or compounds of faces. # @param theName Object name; when specified, this parameter is used # for result publication in the study. Otherwise, if automatic # publication is switched on, default value is used for result name. From e087bbd0639cc0e9ffd05416387007385187bcdd Mon Sep 17 00:00:00 2001 From: skv Date: Thu, 4 Feb 2016 16:29:39 +0300 Subject: [PATCH 42/63] 0052840: Fuse fails if "Remove extra edges" is ON --- src/GEOMImpl/GEOMImpl_PipeDriver.cxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx index ef5b07e79..039bf0027 100644 --- a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx @@ -180,6 +180,8 @@ static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine) //======================================================================= static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder) { + theBuilder.SetForceApproxC1(Standard_True); + theBuilder.Build(); Standard_Boolean isDone = theBuilder.IsDone(); @@ -3125,7 +3127,8 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const else { GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath); - BRepOffsetAPI_MakePipe aMkPipe(aWirePath, aShapeBase, theBestMode); + BRepOffsetAPI_MakePipe aMkPipe + (aWirePath, aShapeBase, theBestMode, Standard_True); if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) { aShape = aMkPipe.Shape(); @@ -3137,7 +3140,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const } else if (theBestMode != GeomFill_IsDiscreteTrihedron) { // Try to use Descrete Trihedron mode. BRepOffsetAPI_MakePipe aMkPipeDescrete - (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron); + (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron, Standard_True); if (aMkPipeDescrete.IsDone()) { aShape = aMkPipeDescrete.Shape(); From 0e330446a29f4acbd571ffd65d0f5ed1c38f88db Mon Sep 17 00:00:00 2001 From: skv Date: Fri, 5 Feb 2016 17:03:36 +0300 Subject: [PATCH 43/63] 0053079: SALOME crashes at Python Dump --- src/GEOM/GEOM_Engine.cxx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/GEOM/GEOM_Engine.cxx b/src/GEOM/GEOM_Engine.cxx index e7921bed4..41be7c204 100644 --- a/src/GEOM/GEOM_Engine.cxx +++ b/src/GEOM/GEOM_Engine.cxx @@ -1278,7 +1278,10 @@ void FillMapOfRef(const Handle(GEOM_Function) &theFunction, const int aRefTag = GetTag(anObjEntry); - theRefMap[anObjTag].push_back(aRefTag); + if (anObjTag != aRefTag) { + // Avoid making references for operations without copy. + theRefMap[anObjTag].push_back(aRefTag); + } } } } From 09357329ca1aeb2b7ceb4af2e8234863ae17a8dc Mon Sep 17 00:00:00 2001 From: vsr Date: Mon, 8 Feb 2016 18:48:44 +0300 Subject: [PATCH 44/63] 0023208: [CEA 1660] GetType function returns 0 with an object resulting from a transformation Update documentation on GEOM_Object::GetType() method. --- idl/GEOM_Gen.idl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 1e572a79f..be4adbbd0 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -299,7 +299,9 @@ module GEOM long GetStudyID(); /*! - * \brief Get internal type of the object (POINT, BOX, CYLINDER, EXTRUSION...). + * \brief Get internal type of operation created this object (POINT, BOX, CYLINDER, EXTRUSION...). + * \note To get topological information on the object, use \ref GEOM_IMeasureOperations::WhatIs() "WhatIs()" + * or \ref GEOM_IMeasureOperations::KindOfShape() "KindOfShape()" operation. */ long GetType(); From 77d971c19f2223b21b60c8aefe4753d345f29a41 Mon Sep 17 00:00:00 2001 From: rnv Date: Mon, 15 Feb 2016 15:39:01 +0300 Subject: [PATCH 45/63] CMake: simplifying Python detection mechanism. --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4dc80fd57..1d4a1a570 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,8 @@ MARK_AS_ADVANCED(SALOME_BUILD_GUI SALOME_GEOM_USE_OPENCV) ## # Various -FIND_PACKAGE(SalomePython REQUIRED) +FIND_PACKAGE(SalomePythonInterp REQUIRED) +FIND_PACKAGE(SalomePythonLibs REQUIRED) FIND_PACKAGE(SalomePThread REQUIRED) FIND_PACKAGE(SalomeSWIG REQUIRED) FIND_PACKAGE(SalomeBoost REQUIRED) From 2a43dbcceb32d847ac6ab7b310b9a116e2c28861 Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 11 Feb 2016 18:26:21 +0300 Subject: [PATCH 46/63] Merge relevant changes from V8_0_0_BR branch --- SalomeGEOMConfig.cmake.in | 48 ++++++++++--------- src/AdvancedGUI/CMakeLists.txt | 1 - src/BREPPlugin/CMakeLists.txt | 1 - src/BasicGUI/BasicGUI_PointDlg.cxx | 10 ++-- src/BasicGUI/CMakeLists.txt | 2 +- src/BlocksGUI/CMakeLists.txt | 3 +- src/BooleanGUI/CMakeLists.txt | 3 +- src/BuildGUI/CMakeLists.txt | 3 +- src/CurveCreator/CMakeLists.txt | 2 +- src/DisplayGUI/CMakeLists.txt | 3 -- src/EntityGUI/CMakeLists.txt | 3 +- src/EntityGUI/EntityGUI_FieldDlg.cxx | 2 +- src/EntityGUI/EntityGUI_SketcherDlg.cxx | 6 +-- src/GEOMBase/CMakeLists.txt | 2 +- src/GEOMFiltersSelection/CMakeLists.txt | 2 - src/GEOMGUI/CMakeLists.txt | 1 - src/GEOMGUI/GEOMGUI.cxx | 14 +++--- src/GEOMToolsGUI/CMakeLists.txt | 2 +- .../GEOMToolsGUI_DeflectionDlg.cxx | 12 ++--- .../GEOMToolsGUI_LineWidthDlg.cxx | 12 ++--- src/GEOMToolsGUI/GEOMToolsGUI_NbIsosDlg.cxx | 12 ++--- src/GEOM_SWIG_WITHIHM/CMakeLists.txt | 1 - src/GenerationGUI/CMakeLists.txt | 2 +- src/GroupGUI/CMakeLists.txt | 3 +- src/GroupGUI/GroupGUI_GroupDlg.cxx | 2 +- src/IGESPlugin/CMakeLists.txt | 1 - src/IGESPlugin/IGESPlugin_ExportDlg.cxx | 2 +- src/Material/CMakeLists.txt | 2 +- src/MeasureGUI/CMakeLists.txt | 3 +- src/OBJECT/CMakeLists.txt | 1 - src/OperationGUI/CMakeLists.txt | 3 +- src/PrimitiveGUI/CMakeLists.txt | 2 +- src/RepairGUI/CMakeLists.txt | 3 +- src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx | 14 +++--- src/RepairGUI/RepairGUI_FuseEdgesDlg.cxx | 4 +- src/RepairGUI/RepairGUI_InspectObjectDlg.cxx | 2 +- src/STEPPlugin/CMakeLists.txt | 1 - src/STEPPlugin/STEPPlugin_ExportDlg.cxx | 2 +- src/STLPlugin/CMakeLists.txt | 1 - src/STLPlugin/STLPlugin_ExportDlg.cxx | 2 +- src/ShapeRecognition/CMakeLists.txt | 2 - src/TransformationGUI/CMakeLists.txt | 3 +- src/VTKPlugin/CMakeLists.txt | 1 - src/VTKPlugin/VTKPlugin_ExportDlg.cxx | 2 +- src/XAOPlugin/CMakeLists.txt | 1 - 45 files changed, 90 insertions(+), 114 deletions(-) diff --git a/SalomeGEOMConfig.cmake.in b/SalomeGEOMConfig.cmake.in index fe0e4b8f5..42db6d36b 100644 --- a/SalomeGEOMConfig.cmake.in +++ b/SalomeGEOMConfig.cmake.in @@ -69,32 +69,34 @@ IF(SALOME_GEOM_USE_OPENCV) LIST(APPEND GEOM_DEFINITIONS "-DWITH_OPENCV") ENDIF() -# For all prerequisites, load the corresponding targets if the package was used +# For all prerequisites, load the corresponding targets if the package was used # in CONFIG mode. This ensures dependent projects link correctly # without having to set LD_LIBRARY_PATH: -SET(_PREREQ @_PREREQ_LIST@) -SET(_PREREQ_CONFIG_DIR @_PREREQ_DIR_LIST@) -SET(_PREREQ_COMPONENTS "@_PREREQ_COMPO_LIST@") -LIST(LENGTH _PREREQ_CONFIG_DIR _list_len) -IF(NOT _list_len EQUAL 0) +SET(_PREREQ_@PROJECT_NAME@ @_PREREQ_LIST@) +SET(_PREREQ_@PROJECT_NAME@_CONFIG_DIR @_PREREQ_DIR_LIST@) +SET(_PREREQ_@PROJECT_NAME@_COMPONENTS "@_PREREQ_COMPO_LIST@") +LIST(LENGTH _PREREQ_@PROJECT_NAME@_CONFIG_DIR _list_len_@PROJECT_NAME@) +IF(NOT _list_len_@PROJECT_NAME@ EQUAL 0) # Another CMake stupidity - FOREACH(... RANGE r) generates r+1 numbers ... - MATH(EXPR _range "${_list_len}-1") - FOREACH(_p RANGE ${_range}) - LIST(GET _PREREQ ${_p} _pkg ) - LIST(GET _PREREQ_CONFIG_DIR ${_p} _pkg_dir) - LIST(GET _PREREQ_COMPONENTS ${_p} _pkg_compo) - MESSAGE(STATUS "===> Reloading targets from ${_pkg} ...") - IF(NOT _pkg_compo) - FIND_PACKAGE(${_pkg} REQUIRED NO_MODULE - PATHS "${_pkg_dir}" - NO_DEFAULT_PATH) - ELSE() - STRING(REPLACE "," ";" _compo_lst "${_pkg_compo}") - MESSAGE(STATUS "===> (components: ${_pkg_compo})") - FIND_PACKAGE(${_pkg} REQUIRED NO_MODULE - COMPONENTS ${_compo_lst} - PATHS "${_pkg_dir}" - NO_DEFAULT_PATH) + MATH(EXPR _range_@PROJECT_NAME@ "${_list_len_@PROJECT_NAME@}-1") + FOREACH(_p_@PROJECT_NAME@ RANGE ${_range_@PROJECT_NAME@}) + LIST(GET _PREREQ_@PROJECT_NAME@ ${_p_@PROJECT_NAME@} _pkg_@PROJECT_NAME@ ) + LIST(GET _PREREQ_@PROJECT_NAME@_CONFIG_DIR ${_p_@PROJECT_NAME@} _pkg_dir_@PROJECT_NAME@) + LIST(GET _PREREQ_@PROJECT_NAME@_COMPONENTS ${_p_@PROJECT_NAME@} _pkg_compo_@PROJECT_NAME@) + IF(NOT OMIT_DETECT_PACKAGE_${_pkg_@PROJECT_NAME@}) + MESSAGE(STATUS "===> Reloading targets from ${_pkg_@PROJECT_NAME@} ...") + IF(NOT _pkg_compo_@PROJECT_NAME@) + FIND_PACKAGE(${_pkg_@PROJECT_NAME@} REQUIRED NO_MODULE + PATHS "${_pkg_dir_@PROJECT_NAME@}" + NO_DEFAULT_PATH) + ELSE() + STRING(REPLACE "," ";" _compo_lst_@PROJECT_NAME@ "${_pkg_compo_@PROJECT_NAME@}") + MESSAGE(STATUS "===> (components: ${_pkg_compo_@PROJECT_NAME@})") + FIND_PACKAGE(${_pkg_@PROJECT_NAME@} REQUIRED NO_MODULE + COMPONENTS ${_compo_lst_@PROJECT_NAME@} + PATHS "${_pkg_dir_@PROJECT_NAME@}" + NO_DEFAULT_PATH) + ENDIF() ENDIF() ENDFOREACH() ENDIF() diff --git a/src/AdvancedGUI/CMakeLists.txt b/src/AdvancedGUI/CMakeLists.txt index b2df1cc47..c97ceb6d6 100755 --- a/src/AdvancedGUI/CMakeLists.txt +++ b/src/AdvancedGUI/CMakeLists.txt @@ -18,7 +18,6 @@ # INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) # --- options --- diff --git a/src/BREPPlugin/CMakeLists.txt b/src/BREPPlugin/CMakeLists.txt index 0372c1e64..df959433d 100644 --- a/src/BREPPlugin/CMakeLists.txt +++ b/src/BREPPlugin/CMakeLists.txt @@ -19,7 +19,6 @@ IF(SALOME_BUILD_GUI) INCLUDE(UseQt4Ext) - INCLUDE(${QT_USE_FILE}) ENDIF() # --- options --- diff --git a/src/BasicGUI/BasicGUI_PointDlg.cxx b/src/BasicGUI/BasicGUI_PointDlg.cxx index 96a989a88..021592e51 100644 --- a/src/BasicGUI/BasicGUI_PointDlg.cxx +++ b/src/BasicGUI/BasicGUI_PointDlg.cxx @@ -995,13 +995,13 @@ void BasicGUI_PointDlg::updateParamCoord(bool theIsUpdate) } } else if (id == GEOM_POINT_SURF) { - GroupOnSurface->TextLabel2->setShown(isParam); - GroupOnSurface->TextLabel3->setShown(isParam); - GroupOnSurface->SpinBox_DX->setShown(isParam); - GroupOnSurface->SpinBox_DY->setShown(isParam); + GroupOnSurface->TextLabel2->setVisible(isParam); + GroupOnSurface->TextLabel3->setVisible(isParam); + GroupOnSurface->SpinBox_DX->setVisible(isParam); + GroupOnSurface->SpinBox_DY->setVisible(isParam); } - GroupXYZ->setShown(!isParam && !isLength); + GroupXYZ->setVisible(!isParam && !isLength); if (theIsUpdate) QTimer::singleShot(50, this, SLOT(updateSize())); diff --git a/src/BasicGUI/CMakeLists.txt b/src/BasicGUI/CMakeLists.txt index 3a4821820..f8d207551 100755 --- a/src/BasicGUI/CMakeLists.txt +++ b/src/BasicGUI/CMakeLists.txt @@ -17,7 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/BlocksGUI/CMakeLists.txt b/src/BlocksGUI/CMakeLists.txt index ebc68572c..810352205 100755 --- a/src/BlocksGUI/CMakeLists.txt +++ b/src/BlocksGUI/CMakeLists.txt @@ -17,8 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -#INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/BooleanGUI/CMakeLists.txt b/src/BooleanGUI/CMakeLists.txt index e7c9b7850..31449e449 100755 --- a/src/BooleanGUI/CMakeLists.txt +++ b/src/BooleanGUI/CMakeLists.txt @@ -17,8 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -#INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/BuildGUI/CMakeLists.txt b/src/BuildGUI/CMakeLists.txt index 37bcff647..301e45725 100755 --- a/src/BuildGUI/CMakeLists.txt +++ b/src/BuildGUI/CMakeLists.txt @@ -17,8 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -#INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/CurveCreator/CMakeLists.txt b/src/CurveCreator/CMakeLists.txt index c085fc69f..dff458676 100644 --- a/src/CurveCreator/CMakeLists.txt +++ b/src/CurveCreator/CMakeLists.txt @@ -18,7 +18,7 @@ # IF(SALOME_BUILD_GUI) - INCLUDE(${QT_USE_FILE}) + INCLUDE(UseQt4Ext) ENDIF(SALOME_BUILD_GUI) # --- options --- diff --git a/src/DisplayGUI/CMakeLists.txt b/src/DisplayGUI/CMakeLists.txt index 7a9d92208..bfca525b2 100755 --- a/src/DisplayGUI/CMakeLists.txt +++ b/src/DisplayGUI/CMakeLists.txt @@ -17,9 +17,6 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -#INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) - # --- options --- # additional include directories diff --git a/src/EntityGUI/CMakeLists.txt b/src/EntityGUI/CMakeLists.txt index 0bb93f921..10b849be2 100755 --- a/src/EntityGUI/CMakeLists.txt +++ b/src/EntityGUI/CMakeLists.txt @@ -17,8 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -#INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/EntityGUI/EntityGUI_FieldDlg.cxx b/src/EntityGUI/EntityGUI_FieldDlg.cxx index 6e887f941..aab2def9b 100644 --- a/src/EntityGUI/EntityGUI_FieldDlg.cxx +++ b/src/EntityGUI/EntityGUI_FieldDlg.cxx @@ -1695,7 +1695,7 @@ void EntityGUI_FieldDlg::activateSelection() TopoDS_Shape aSubShape = myShapeMap( index ); QString anEntry = QString( "TEMP_" ) + aMainEntry.in() + QString("_%1").arg(index); Handle(SALOME_InteractiveObject) io = - new SALOME_InteractiveObject(anEntry.toAscii(), "GEOM", "TEMP_IO"); + new SALOME_InteractiveObject(anEntry.toLatin1(), "GEOM", "TEMP_IO"); aDisplayer->SetColor( aCol ); SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView); if (aPrs) { diff --git a/src/EntityGUI/EntityGUI_SketcherDlg.cxx b/src/EntityGUI/EntityGUI_SketcherDlg.cxx index 6b0248b08..6749738fd 100644 --- a/src/EntityGUI/EntityGUI_SketcherDlg.cxx +++ b/src/EntityGUI/EntityGUI_SketcherDlg.cxx @@ -1143,7 +1143,7 @@ void EntityGUI_SketcherDlg::ClickOnEnd() } QString Command = myCommand.join( "" ); - Sketcher_Profile aProfile = Sketcher_Profile( Command.toAscii() ); + Sketcher_Profile aProfile = Sketcher_Profile( Command.toLatin1() ); bool isDone = false; TopoDS_Shape myShape = aProfile.GetShape( &isDone ); if ( isDone ) { @@ -2341,12 +2341,12 @@ bool EntityGUI_SketcherDlg::execute( ObjectList& objects ) //Last Shape QString Command1 = myCommand.join( "" ); - Sketcher_Profile aProfile1( Command1.toAscii() ); + Sketcher_Profile aProfile1( Command1.toLatin1() ); myShape1 = aProfile1.GetShape(); //Current Shape QString Command2 = Command1 + GetNewCommand( aParameters ); - Sketcher_Profile aProfile2( Command2.toAscii() ); + Sketcher_Profile aProfile2( Command2.toLatin1() ); myShape2 = aProfile2.GetShape( &isDone, &error ); //Error Message diff --git a/src/GEOMBase/CMakeLists.txt b/src/GEOMBase/CMakeLists.txt index f3cc03f26..1aa48c6ee 100755 --- a/src/GEOMBase/CMakeLists.txt +++ b/src/GEOMBase/CMakeLists.txt @@ -17,7 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/GEOMFiltersSelection/CMakeLists.txt b/src/GEOMFiltersSelection/CMakeLists.txt index d999542d4..237fe4e35 100755 --- a/src/GEOMFiltersSelection/CMakeLists.txt +++ b/src/GEOMFiltersSelection/CMakeLists.txt @@ -17,8 +17,6 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -INCLUDE(${QT_USE_FILE}) - # --- options --- # additional include directories diff --git a/src/GEOMGUI/CMakeLists.txt b/src/GEOMGUI/CMakeLists.txt index c5e9e928f..065d2caf8 100755 --- a/src/GEOMGUI/CMakeLists.txt +++ b/src/GEOMGUI/CMakeLists.txt @@ -18,7 +18,6 @@ # INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) # --- options --- diff --git a/src/GEOMGUI/GEOMGUI.cxx b/src/GEOMGUI/GEOMGUI.cxx index f74393250..9425cb809 100644 --- a/src/GEOMGUI/GEOMGUI.cxx +++ b/src/GEOMGUI/GEOMGUI.cxx @@ -54,7 +54,7 @@ GEOMGUI::~GEOMGUI() //================================================================================= bool GEOMGUI::OnGUIEvent( int /*theCommandID*/, SUIT_Desktop* /*parent*/, const QVariant& /*theParam*/ ) { - return TRUE; + return true; } //================================================================================= @@ -63,17 +63,17 @@ bool GEOMGUI::OnGUIEvent( int /*theCommandID*/, SUIT_Desktop* /*parent*/, const //================================================================================= bool GEOMGUI::OnGUIEvent( int /*theCommandID*/, SUIT_Desktop* /*parent*/ ) { - return TRUE; + return true; } //================================================================================= // class : GEOMGUI::OnMousePress -// purpose : Mouse press event processing. Should return FALSE to let the event +// purpose : Mouse press event processing. Should return false to let the event // be processed further. //================================================================================= bool GEOMGUI::OnMousePress( QMouseEvent* /*pe*/, SUIT_Desktop* /*parent*/, SUIT_ViewWindow* /*studyFrame*/ ) { - return FALSE; + return false; } //================================================================================= @@ -82,7 +82,7 @@ bool GEOMGUI::OnMousePress( QMouseEvent* /*pe*/, SUIT_Desktop* /*parent*/, SUIT_ //================================================================================= bool GEOMGUI::OnMouseMove( QMouseEvent* /*pe*/, SUIT_Desktop* /*parent*/, SUIT_ViewWindow* /*studyFrame*/ ) { - return TRUE; + return true; } //================================================================================= @@ -91,7 +91,7 @@ bool GEOMGUI::OnMouseMove( QMouseEvent* /*pe*/, SUIT_Desktop* /*parent*/, SUIT_V //================================================================================= bool GEOMGUI::OnMouseRelease( QMouseEvent* /*pe*/, SUIT_Desktop* /*parent*/, SUIT_ViewWindow* /*studyFrame*/ ) { - return TRUE; + return true; } //================================================================================= @@ -100,7 +100,7 @@ bool GEOMGUI::OnMouseRelease( QMouseEvent* /*pe*/, SUIT_Desktop* /*parent*/, SUI //================================================================================= bool GEOMGUI::OnKeyPress( QKeyEvent* /*pe*/, SUIT_Desktop* /*parent*/, SUIT_ViewWindow* /*studyFrame*/ ) { - return TRUE; + return true; } //================================================================================= diff --git a/src/GEOMToolsGUI/CMakeLists.txt b/src/GEOMToolsGUI/CMakeLists.txt index cb3e004cb..e6438e07d 100755 --- a/src/GEOMToolsGUI/CMakeLists.txt +++ b/src/GEOMToolsGUI/CMakeLists.txt @@ -17,7 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_DeflectionDlg.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_DeflectionDlg.cxx index f977e08d9..0a8e4ffde 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_DeflectionDlg.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI_DeflectionDlg.cxx @@ -43,7 +43,7 @@ // purpose : Constructs a GEOMToolsGUI_DeflectionDlg which is a child of 'parent', with the // name 'name' and widget flags set to 'f'. // The dialog will by default be modeless, unless you set 'modal' to -// TRUE to construct a modal dialog. +// true to construct a modal dialog. //================================================================================= GEOMToolsGUI_DeflectionDlg::GEOMToolsGUI_DeflectionDlg (QWidget* parent) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint) @@ -52,7 +52,7 @@ GEOMToolsGUI_DeflectionDlg::GEOMToolsGUI_DeflectionDlg (QWidget* parent) setModal(true); setWindowTitle(tr("GEOM_DEFLECTION_TLT")); - setSizeGripEnabled(TRUE); + setSizeGripEnabled(true); QGridLayout* MyDialogLayout = new QGridLayout(this); MyDialogLayout->setSpacing(6); MyDialogLayout->setMargin(11); @@ -101,8 +101,8 @@ GEOMToolsGUI_DeflectionDlg::GEOMToolsGUI_DeflectionDlg (QWidget* parent) QPushButton* buttonOk = new QPushButton (GroupButtons); buttonOk->setObjectName("buttonOk"); buttonOk->setText(tr("GEOM_BUT_OK")); - buttonOk->setAutoDefault(TRUE); - buttonOk->setDefault(TRUE); + buttonOk->setAutoDefault(true); + buttonOk->setDefault(true); GroupButtonsLayout->addWidget(buttonOk, 0, 0); GroupButtonsLayout->addItem(new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 1); @@ -110,13 +110,13 @@ GEOMToolsGUI_DeflectionDlg::GEOMToolsGUI_DeflectionDlg (QWidget* parent) QPushButton* buttonCancel = new QPushButton (GroupButtons); buttonCancel->setObjectName("buttonCancel"); buttonCancel->setText(tr("GEOM_BUT_CANCEL")); - buttonCancel->setAutoDefault(TRUE); + buttonCancel->setAutoDefault(true); GroupButtonsLayout->addWidget(buttonCancel, 0, 1); QPushButton* buttonHelp = new QPushButton (GroupButtons); buttonHelp->setObjectName("buttonHelp"); buttonHelp->setText(tr("GEOM_BUT_HELP")); - buttonHelp->setAutoDefault(TRUE); + buttonHelp->setAutoDefault(true); GroupButtonsLayout->addWidget(buttonHelp, 0, 2); /***************************************************************/ diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_LineWidthDlg.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_LineWidthDlg.cxx index 95713739c..82985ae1a 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_LineWidthDlg.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI_LineWidthDlg.cxx @@ -44,7 +44,7 @@ // purpose : Constructs a GEOMToolsGUI_LineWidthDlg which is a child of 'parent', with the // name 'name' and widget flags set to 'f'. // The dialog will by default be modeless, unless you set 'modal' to -// TRUE to construct a modal dialog. +// true to construct a modal dialog. //================================================================================= GEOMToolsGUI_LineWidthDlg::GEOMToolsGUI_LineWidthDlg (QWidget* parent, const QString& title) @@ -54,7 +54,7 @@ GEOMToolsGUI_LineWidthDlg::GEOMToolsGUI_LineWidthDlg (QWidget* parent, const QSt setModal(true); setWindowTitle(tr(title.toLatin1().constData())); - setSizeGripEnabled(TRUE); + setSizeGripEnabled(true); QGridLayout* MyDialogLayout = new QGridLayout(this); MyDialogLayout->setSpacing(6); MyDialogLayout->setMargin(11); @@ -95,8 +95,8 @@ GEOMToolsGUI_LineWidthDlg::GEOMToolsGUI_LineWidthDlg (QWidget* parent, const QSt QPushButton* buttonOk = new QPushButton (GroupButtons); buttonOk->setObjectName("buttonOk"); buttonOk->setText(tr("GEOM_BUT_OK")); - buttonOk->setAutoDefault(TRUE); - buttonOk->setDefault(TRUE); + buttonOk->setAutoDefault(true); + buttonOk->setDefault(true); GroupButtonsLayout->addWidget(buttonOk, 0, 0); GroupButtonsLayout->addItem(new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 1); @@ -104,13 +104,13 @@ GEOMToolsGUI_LineWidthDlg::GEOMToolsGUI_LineWidthDlg (QWidget* parent, const QSt QPushButton* buttonCancel = new QPushButton (GroupButtons); buttonCancel->setObjectName("buttonCancel"); buttonCancel->setText(tr("GEOM_BUT_CANCEL")); - buttonCancel->setAutoDefault(TRUE); + buttonCancel->setAutoDefault(true); GroupButtonsLayout->addWidget(buttonCancel, 0, 1); QPushButton* buttonHelp = new QPushButton (GroupButtons); buttonHelp->setObjectName("buttonHelp"); buttonHelp->setText(tr("GEOM_BUT_HELP")); - buttonHelp->setAutoDefault(TRUE); + buttonHelp->setAutoDefault(true); GroupButtonsLayout->addWidget(buttonHelp, 0, 2); /***************************************************************/ diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_NbIsosDlg.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_NbIsosDlg.cxx index ab1ea6692..4e7541f04 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_NbIsosDlg.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI_NbIsosDlg.cxx @@ -44,7 +44,7 @@ // purpose : Constructs a GEOMToolsGUI_NbIsosDlg which is a child of 'parent', with the // name 'name' and widget flags set to 'f'. // The dialog will by default be modeless, unless you set 'modal' to -// TRUE to construct a modal dialog. +// true to construct a modal dialog. //================================================================================= GEOMToolsGUI_NbIsosDlg::GEOMToolsGUI_NbIsosDlg(QWidget* parent ) :QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ) @@ -53,7 +53,7 @@ GEOMToolsGUI_NbIsosDlg::GEOMToolsGUI_NbIsosDlg(QWidget* parent ) setModal( true ); setWindowTitle( tr( "GEOM_MEN_ISOS" ) ); - setSizeGripEnabled(TRUE); + setSizeGripEnabled(true); QGridLayout* MyDialogLayout = new QGridLayout(this); MyDialogLayout->setSpacing(6); MyDialogLayout->setMargin(11); @@ -101,8 +101,8 @@ GEOMToolsGUI_NbIsosDlg::GEOMToolsGUI_NbIsosDlg(QWidget* parent ) QPushButton* buttonOk = new QPushButton( GroupButtons ); buttonOk->setObjectName( "buttonOk" ); buttonOk->setText( tr( "GEOM_BUT_OK" ) ) ; - buttonOk->setAutoDefault( TRUE ); - buttonOk->setDefault( TRUE ); + buttonOk->setAutoDefault( true ); + buttonOk->setDefault( true ); GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 ); @@ -110,13 +110,13 @@ GEOMToolsGUI_NbIsosDlg::GEOMToolsGUI_NbIsosDlg(QWidget* parent ) QPushButton* buttonCancel = new QPushButton( GroupButtons ); buttonCancel->setObjectName( "buttonCancel" ); buttonCancel->setText( tr( "GEOM_BUT_CANCEL" ) ) ; - buttonCancel->setAutoDefault( TRUE ); + buttonCancel->setAutoDefault( true ); GroupButtonsLayout->addWidget( buttonCancel, 0, 1 ); QPushButton* buttonHelp = new QPushButton( GroupButtons ); buttonHelp->setObjectName( "buttonHelp" ); buttonHelp->setText( tr( "GEOM_BUT_HELP" ) ) ; - buttonHelp->setAutoDefault( TRUE ); + buttonHelp->setAutoDefault( true ); GroupButtonsLayout->addWidget( buttonHelp, 0, 2 ); /***************************************************************/ diff --git a/src/GEOM_SWIG_WITHIHM/CMakeLists.txt b/src/GEOM_SWIG_WITHIHM/CMakeLists.txt index 99e8d1856..4b0607795 100755 --- a/src/GEOM_SWIG_WITHIHM/CMakeLists.txt +++ b/src/GEOM_SWIG_WITHIHM/CMakeLists.txt @@ -18,7 +18,6 @@ # INCLUDE(${SWIG_USE_FILE}) -INCLUDE(${QT_USE_FILE}) # --- options --- diff --git a/src/GenerationGUI/CMakeLists.txt b/src/GenerationGUI/CMakeLists.txt index b60f1dde6..21341b341 100755 --- a/src/GenerationGUI/CMakeLists.txt +++ b/src/GenerationGUI/CMakeLists.txt @@ -17,7 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/GroupGUI/CMakeLists.txt b/src/GroupGUI/CMakeLists.txt index 73e18271b..69d998b91 100755 --- a/src/GroupGUI/CMakeLists.txt +++ b/src/GroupGUI/CMakeLists.txt @@ -17,8 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -#INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/GroupGUI/GroupGUI_GroupDlg.cxx b/src/GroupGUI/GroupGUI_GroupDlg.cxx index aec21881f..c85609615 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.cxx +++ b/src/GroupGUI/GroupGUI_GroupDlg.cxx @@ -1098,7 +1098,7 @@ void GroupGUI_GroupDlg::activateSelection() int index = aSubShapesMap.FindIndex(aSubShape); QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index); Handle(SALOME_InteractiveObject) io = - new SALOME_InteractiveObject(anEntry.toAscii(), "GEOM", "TEMP_IO"); + new SALOME_InteractiveObject(anEntry.toLatin1(), "GEOM", "TEMP_IO"); if ( myGroupIdList.contains( index ) ) { aDisplayer->SetColor( aCol ); } diff --git a/src/IGESPlugin/CMakeLists.txt b/src/IGESPlugin/CMakeLists.txt index b380989f4..f286bbb16 100644 --- a/src/IGESPlugin/CMakeLists.txt +++ b/src/IGESPlugin/CMakeLists.txt @@ -19,7 +19,6 @@ IF(SALOME_BUILD_GUI) INCLUDE(UseQt4Ext) - INCLUDE(${QT_USE_FILE}) ENDIF() # --- options --- diff --git a/src/IGESPlugin/IGESPlugin_ExportDlg.cxx b/src/IGESPlugin/IGESPlugin_ExportDlg.cxx index cb667070f..a49db7ffc 100644 --- a/src/IGESPlugin/IGESPlugin_ExportDlg.cxx +++ b/src/IGESPlugin/IGESPlugin_ExportDlg.cxx @@ -69,7 +69,7 @@ QString IGESPlugin_ExportDlg::getFileName( const QString& initial, const QString IGESPlugin_ExportDlg fd( parent ); fd.setFileMode( AnyFile ); - fd.setFilters( fls ); + fd.setNameFilters( fls ); fd.setWindowTitle( caption ); if ( !tmpfilename.isEmpty() ) fd.processPath( tmpfilename ); diff --git a/src/Material/CMakeLists.txt b/src/Material/CMakeLists.txt index f8957e562..94ab5acc2 100755 --- a/src/Material/CMakeLists.txt +++ b/src/Material/CMakeLists.txt @@ -17,7 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/MeasureGUI/CMakeLists.txt b/src/MeasureGUI/CMakeLists.txt index eaae08f27..ee8ffdf0d 100755 --- a/src/MeasureGUI/CMakeLists.txt +++ b/src/MeasureGUI/CMakeLists.txt @@ -17,8 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -#INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/OBJECT/CMakeLists.txt b/src/OBJECT/CMakeLists.txt index 60a7497ca..7330c9553 100755 --- a/src/OBJECT/CMakeLists.txt +++ b/src/OBJECT/CMakeLists.txt @@ -17,7 +17,6 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -INCLUDE(${QT_USE_FILE}) INCLUDE(${VTK_USE_FILE}) # --- options --- diff --git a/src/OperationGUI/CMakeLists.txt b/src/OperationGUI/CMakeLists.txt index 4fa28ace0..2ff65aed2 100755 --- a/src/OperationGUI/CMakeLists.txt +++ b/src/OperationGUI/CMakeLists.txt @@ -17,8 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -#INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/PrimitiveGUI/CMakeLists.txt b/src/PrimitiveGUI/CMakeLists.txt index e90b50c65..e24ab15d4 100755 --- a/src/PrimitiveGUI/CMakeLists.txt +++ b/src/PrimitiveGUI/CMakeLists.txt @@ -17,7 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/RepairGUI/CMakeLists.txt b/src/RepairGUI/CMakeLists.txt index d9ae6fa29..c859bc5e9 100755 --- a/src/RepairGUI/CMakeLists.txt +++ b/src/RepairGUI/CMakeLists.txt @@ -17,8 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -#INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx b/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx index 673f29d6b..21f39aef9 100644 --- a/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx +++ b/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx @@ -127,13 +127,13 @@ RepairGUI_DivideEdgeDlg::RepairGUI_DivideEdgeDlg( GeometryGUI* theGeometryGUI, Q //======================================================================= void RepairGUI_DivideEdgeDlg::ConstructorsClicked( int constructorId ) { - myIsParameterGr->button( 0 )->setShown( constructorId == BY_PARAM ); - myIsParameterGr->button( 1 )->setShown( constructorId == BY_PARAM ); - myValEdt ->setShown( constructorId == BY_PARAM ); - myValLbl ->setShown( constructorId == BY_PARAM ); - GroupPoints->TextLabel2 ->setShown( constructorId == BY_POINT_PROJ ); - GroupPoints->PushButton2 ->setShown( constructorId == BY_POINT_PROJ ); - GroupPoints->LineEdit2 ->setShown( constructorId == BY_POINT_PROJ ); + myIsParameterGr->button( 0 )->setVisible( constructorId == BY_PARAM ); + myIsParameterGr->button( 1 )->setVisible( constructorId == BY_PARAM ); + myValEdt ->setVisible( constructorId == BY_PARAM ); + myValLbl ->setVisible( constructorId == BY_PARAM ); + GroupPoints->TextLabel2 ->setVisible( constructorId == BY_POINT_PROJ ); + GroupPoints->PushButton2 ->setVisible( constructorId == BY_POINT_PROJ ); + GroupPoints->LineEdit2 ->setVisible( constructorId == BY_POINT_PROJ ); initSelection(); diff --git a/src/RepairGUI/RepairGUI_FuseEdgesDlg.cxx b/src/RepairGUI/RepairGUI_FuseEdgesDlg.cxx index ac1372811..d6671dbbf 100644 --- a/src/RepairGUI/RepairGUI_FuseEdgesDlg.cxx +++ b/src/RepairGUI/RepairGUI_FuseEdgesDlg.cxx @@ -69,8 +69,8 @@ RepairGUI_FuseEdgesDlg::RepairGUI_FuseEdgesDlg (GeometryGUI* theGeometryGUI, GroupVertexes->LineEdit1->setReadOnly(true); GroupVertexes->LineEdit2->setReadOnly(true); - GroupVertexes->TextLabel3->setShown(false); - GroupVertexes->SpinBox_DX->setShown(false); + GroupVertexes->TextLabel3->setVisible(false); + GroupVertexes->SpinBox_DX->setVisible(false); QVBoxLayout* layout = new QVBoxLayout (centralWidget()); layout->setMargin(0); diff --git a/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx b/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx index a66f9c18e..8d3a9f3a6 100644 --- a/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx +++ b/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx @@ -145,7 +145,7 @@ RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem myShape( shape ), myTolerance (theTolerance) { - myIO = new SALOME_InteractiveObject( entry.toAscii(), "GEOM", "TEMP_IO" ); + myIO = new SALOME_InteractiveObject( entry.toLatin1(), "GEOM", "TEMP_IO" ); setFlags( flags() | Qt::ItemIsEditable ); } diff --git a/src/STEPPlugin/CMakeLists.txt b/src/STEPPlugin/CMakeLists.txt index 52d210920..db71d3b24 100644 --- a/src/STEPPlugin/CMakeLists.txt +++ b/src/STEPPlugin/CMakeLists.txt @@ -19,7 +19,6 @@ IF(SALOME_BUILD_GUI) INCLUDE(UseQt4Ext) - INCLUDE(${QT_USE_FILE}) ENDIF() # --- options --- diff --git a/src/STEPPlugin/STEPPlugin_ExportDlg.cxx b/src/STEPPlugin/STEPPlugin_ExportDlg.cxx index 2f8124b29..476934dbf 100644 --- a/src/STEPPlugin/STEPPlugin_ExportDlg.cxx +++ b/src/STEPPlugin/STEPPlugin_ExportDlg.cxx @@ -89,7 +89,7 @@ QString STEPPlugin_ExportDlg::getFileName(const QString &theInitial, STEPPlugin_ExportDlg aDlg(theParent); aDlg.setFileMode(AnyFile); - aDlg.setFilters(aFls); + aDlg.setNameFilters(aFls); aDlg.setWindowTitle(theCaption); if (!aTmpFileName.isEmpty()) { diff --git a/src/STLPlugin/CMakeLists.txt b/src/STLPlugin/CMakeLists.txt index 954610a78..a3ccb8b7f 100644 --- a/src/STLPlugin/CMakeLists.txt +++ b/src/STLPlugin/CMakeLists.txt @@ -19,7 +19,6 @@ IF(SALOME_BUILD_GUI) INCLUDE(UseQt4Ext) - INCLUDE(${QT_USE_FILE}) ENDIF() # --- options --- diff --git a/src/STLPlugin/STLPlugin_ExportDlg.cxx b/src/STLPlugin/STLPlugin_ExportDlg.cxx index 05616e15d..0d36f35e7 100644 --- a/src/STLPlugin/STLPlugin_ExportDlg.cxx +++ b/src/STLPlugin/STLPlugin_ExportDlg.cxx @@ -175,7 +175,7 @@ QString STLPlugin_ExportDlg::getFileName( const Handle(SALOME_InteractiveObject) STLPlugin_ExportDlg fd( io, parent ); fd.setFileMode( AnyFile ); - fd.setFilters( fls ); + fd.setNameFilters( fls ); fd.setWindowTitle( caption ); if ( !tmpfilename.isEmpty() ) fd.processPath( tmpfilename ); diff --git a/src/ShapeRecognition/CMakeLists.txt b/src/ShapeRecognition/CMakeLists.txt index 61f4072c6..a46f02c81 100755 --- a/src/ShapeRecognition/CMakeLists.txt +++ b/src/ShapeRecognition/CMakeLists.txt @@ -17,8 +17,6 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -INCLUDE( ${QT_USE_FILE} ) - # --- options --- # additional include directories diff --git a/src/TransformationGUI/CMakeLists.txt b/src/TransformationGUI/CMakeLists.txt index 2b4b75858..5884b506c 100755 --- a/src/TransformationGUI/CMakeLists.txt +++ b/src/TransformationGUI/CMakeLists.txt @@ -17,8 +17,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -#INCLUDE(UseQt4Ext) -INCLUDE(${QT_USE_FILE}) +INCLUDE(UseQt4Ext) # --- options --- diff --git a/src/VTKPlugin/CMakeLists.txt b/src/VTKPlugin/CMakeLists.txt index 9f67135eb..86d927d41 100644 --- a/src/VTKPlugin/CMakeLists.txt +++ b/src/VTKPlugin/CMakeLists.txt @@ -19,7 +19,6 @@ IF(SALOME_BUILD_GUI) INCLUDE(UseQt4Ext) - INCLUDE(${QT_USE_FILE}) ENDIF() # --- options --- diff --git a/src/VTKPlugin/VTKPlugin_ExportDlg.cxx b/src/VTKPlugin/VTKPlugin_ExportDlg.cxx index b4af670b5..40e69f4f1 100644 --- a/src/VTKPlugin/VTKPlugin_ExportDlg.cxx +++ b/src/VTKPlugin/VTKPlugin_ExportDlg.cxx @@ -99,7 +99,7 @@ QString VTKPlugin_ExportDlg::getFileName( const Handle(SALOME_InteractiveObject) VTKPlugin_ExportDlg fd( io, parent ); fd.setFileMode( AnyFile ); - fd.setFilters( fls ); + fd.setNameFilters( fls ); fd.setWindowTitle( caption ); if ( !tmpfilename.isEmpty() ) fd.processPath( tmpfilename ); diff --git a/src/XAOPlugin/CMakeLists.txt b/src/XAOPlugin/CMakeLists.txt index 47d6a2ff3..6634a1ac8 100644 --- a/src/XAOPlugin/CMakeLists.txt +++ b/src/XAOPlugin/CMakeLists.txt @@ -19,7 +19,6 @@ IF(SALOME_BUILD_GUI) INCLUDE(UseQt4Ext) - INCLUDE(${QT_USE_FILE}) ENDIF() # --- options --- From 9361e2c00ab6ab333b32af580352ae6e8f654401 Mon Sep 17 00:00:00 2001 From: skv Date: Tue, 16 Feb 2016 17:19:14 +0300 Subject: [PATCH 47/63] 0023216: [CEA 1691] Import the compounds with their names from a STEP file --- idl/STEPPlugin.idl | 6 +- src/GEOM_I_Superv/GEOM_Superv_i.cc | 2 +- src/GEOM_SWIG/STEPPluginBuilder.py | 16 +- src/STEPPlugin/CMakeLists.txt | 3 + src/STEPPlugin/STEPPlugin_GUI.cxx | 13 +- src/STEPPlugin/STEPPlugin_IECallBack.cxx | 2 +- src/STEPPlugin/STEPPlugin_IImport.hxx | 11 +- src/STEPPlugin/STEPPlugin_IOperations.cxx | 14 +- src/STEPPlugin/STEPPlugin_IOperations.hxx | 5 +- src/STEPPlugin/STEPPlugin_IOperations_i.cc | 12 +- src/STEPPlugin/STEPPlugin_IOperations_i.hh | 2 +- src/STEPPlugin/STEPPlugin_ImportDlg.cxx | 94 ++++++ src/STEPPlugin/STEPPlugin_ImportDlg.h | 52 ++++ src/STEPPlugin/STEPPlugin_ImportDriver.cxx | 328 ++++++++++++++++++--- src/STEPPlugin/STEPPlugin_msg_en.ts | 7 + 15 files changed, 509 insertions(+), 58 deletions(-) create mode 100644 src/STEPPlugin/STEPPlugin_ImportDlg.cxx create mode 100644 src/STEPPlugin/STEPPlugin_ImportDlg.h diff --git a/idl/STEPPlugin.idl b/idl/STEPPlugin.idl index ba1a74ec8..9caf6f373 100644 --- a/idl/STEPPlugin.idl +++ b/idl/STEPPlugin.idl @@ -64,10 +64,14 @@ module GEOM * \param theIsIgnoreUnits If True, file length units will be ignored (set to 'meter') * and result model will be scaled, if its units are not meters. * If False (default), file length units will be taken into account. + * \param IsCreateAssemblies If True, for each assembly compound is created + * in the result. If False Compounds that contain a + * single shape are eliminated from the result. * \return List of GEOM_Objects, containing the created shape and propagation groups. */ GEOM::ListOfGO ImportSTEP( in string theFileName, - in boolean theIsIgnoreUnits ); + in boolean theIsIgnoreUnits, + in boolean IsCreateAssemblies); /*! * \brief Read a value of parameter from a file, containing a shape. diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.cc b/src/GEOM_I_Superv/GEOM_Superv_i.cc index 662b2c768..a229accac 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.cc +++ b/src/GEOM_I_Superv/GEOM_Superv_i.cc @@ -3579,7 +3579,7 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::ImportSTEP( const char* theFileName, beginService( " GEOM_Superv_i::ImportSTEP" ); MESSAGE("GEOM_Superv_i::ImportSTEP"); getSTEPPluginOp(); - GEOM::ListOfGO* aSeq = mySTEPOp->ImportSTEP(theFileName, theIsIgnoreUnits ); + GEOM::ListOfGO* aSeq = mySTEPOp->ImportSTEP(theFileName, theIsIgnoreUnits, false ); GEOM::GEOM_Object_ptr anObj; if (aSeq->length() > 0) { diff --git a/src/GEOM_SWIG/STEPPluginBuilder.py b/src/GEOM_SWIG/STEPPluginBuilder.py index 1ee4fc6c7..896c0f7d6 100644 --- a/src/GEOM_SWIG/STEPPluginBuilder.py +++ b/src/GEOM_SWIG/STEPPluginBuilder.py @@ -54,6 +54,9 @@ def ExportSTEP(self, theObject, theFileName, theUnit=GEOM.LU_METER): # @param theIsIgnoreUnits If True, file length units will be ignored (set to 'meter') # and result model will be scaled, if its units are not meters. # If False (default), file length units will be taken into account. +# @param IsCreateAssemblies If True, for each assembly compound is created in +# the result. If False Compounds that contain a single shape +# are eliminated from the result. # @param theName Object name; when specified, this parameter is used # for result publication in the study. Otherwise, if automatic # publication is switched on, default value is used for result name. @@ -67,7 +70,8 @@ def ExportSTEP(self, theObject, theFileName, theUnit=GEOM.LU_METER): # # @ref swig_Import_Export "Example" # @ingroup l2_import_export -def ImportSTEP(self, theFileName, theIsIgnoreUnits = False, theName=None): +def ImportSTEP(self, theFileName, theIsIgnoreUnits = False, + IsCreateAssemblies = False, theName=None): """ Import a shape from the STEP file with given name. @@ -76,6 +80,9 @@ def ImportSTEP(self, theFileName, theIsIgnoreUnits = False, theName=None): ignoreUnits If True, file length units will be ignored (set to 'meter') and result model will be scaled, if its units are not meters. If False (default), file length units will be taken into account. + IsCreateAssemblies If True, for each assembly compound is created in + the result. If False Compounds that contain a single shape + are eliminated from the result. theName Object name; when specified, this parameter is used for result publication in the study. Otherwise, if automatic publication is switched on, default value is used for result name. @@ -94,13 +101,18 @@ def ImportSTEP(self, theFileName, theIsIgnoreUnits = False, theName=None): anOp = GetSTEPPluginOperations(self) anIsIgnoreUnits = theIsIgnoreUnits + anIsCreateAssemblies = IsCreateAssemblies; aName = theName if isinstance( theIsIgnoreUnits, basestring ): anIsIgnoreUnits = False aName = theIsIgnoreUnits pass + elif isinstance( IsCreateAssemblies, basestring ): + anIsCreateAssemblies = False + aName = IsCreateAssemblies + pass - aListObj = anOp.ImportSTEP(theFileName,anIsIgnoreUnits) + aListObj = anOp.ImportSTEP(theFileName,anIsIgnoreUnits,anIsCreateAssemblies) RaiseIfFailed("ImportSTEP", anOp) aNbObj = len(aListObj) if aNbObj > 0: diff --git a/src/STEPPlugin/CMakeLists.txt b/src/STEPPlugin/CMakeLists.txt index db71d3b24..efd69970a 100644 --- a/src/STEPPlugin/CMakeLists.txt +++ b/src/STEPPlugin/CMakeLists.txt @@ -94,6 +94,7 @@ SET(STEPPluginEngine_HEADERS STEPPlugin_IExport.hxx STEPPlugin_IImport.hxx STEPPlugin_ImportDriver.hxx + STEPPlugin_ImportDlg.h STEPPlugin_ExportDlg.h STEPPlugin_ExportDriver.hxx STEPPlugin_IECallBack.hxx @@ -104,6 +105,7 @@ IF(SALOME_BUILD_GUI) SET(_moc_HEADERS STEPPlugin_GUI.h STEPPlugin_ExportDlg.h + STEPPlugin_ImportDlg.h ) ENDIF() @@ -116,6 +118,7 @@ IF(SALOME_BUILD_GUI) SET(STEPPluginGUI_SOURCES STEPPlugin_GUI.cxx STEPPlugin_ExportDlg.cxx + STEPPlugin_ImportDlg.cxx ${_moc_SOURCES} ) ENDIF() diff --git a/src/STEPPlugin/STEPPlugin_GUI.cxx b/src/STEPPlugin/STEPPlugin_GUI.cxx index 5543266d7..2986dea4b 100644 --- a/src/STEPPlugin/STEPPlugin_GUI.cxx +++ b/src/STEPPlugin/STEPPlugin_GUI.cxx @@ -38,6 +38,7 @@ #include "GEOM_Displayer.h" #include "GEOM_GenericObjPtr.h" #include "STEPPlugin_ExportDlg.h" +#include "STEPPlugin_ImportDlg.h" #include #include CORBA_SERVER_HEADER(STEPPlugin) @@ -118,10 +119,11 @@ bool STEPPlugin_GUI::importSTEP( SUIT_Desktop* parent ) STEPOpPtr stepOp = GEOM::ISTEPOperations::_narrow( op ); if ( stepOp.isNull() ) return false; - QStringList fileNames = app->getOpenFileNames( SUIT_FileDlg::getLastVisitedPath().isEmpty() ? QDir::currentPath() : QString(""), - tr( "STEP_FILES" ), - tr( "IMPORT_TITLE" ), - parent ); + bool isCreateAssemblies = true; + QStringList fileNames = STEPPlugin_ImportDlg::getOpenFileNames + (SUIT_FileDlg::getLastVisitedPath().isEmpty() ? QDir::currentPath() : QString(""), + tr("STEP_FILES"), tr("IMPORT_TITLE"), parent, isCreateAssemblies); + if ( fileNames.count() > 0 ) { QStringList entryList; @@ -175,7 +177,8 @@ bool STEPPlugin_GUI::importSTEP( SUIT_Desktop* parent ) } } - GEOM::ListOfGO_var result = stepOp->ImportSTEP( fileName.toUtf8().constData(), ignoreUnits ); + GEOM::ListOfGO_var result = stepOp->ImportSTEP + (fileName.toUtf8().constData(), ignoreUnits, isCreateAssemblies); if ( result->length() > 0 && stepOp->IsDone() ) { GEOM::GEOM_Object_var main = result[0]; diff --git a/src/STEPPlugin/STEPPlugin_IECallBack.cxx b/src/STEPPlugin/STEPPlugin_IECallBack.cxx index ac0869716..b745f0d04 100644 --- a/src/STEPPlugin/STEPPlugin_IECallBack.cxx +++ b/src/STEPPlugin/STEPPlugin_IECallBack.cxx @@ -70,7 +70,7 @@ STEPPlugin_IECallBack::Import( int theDocId, { STEPPlugin_IOperations* aPluginOperations = STEPPlugin_OperationsCreator::get( GetEngine(), theDocId ); bool anIsIgnoreUnits = ( theFormatName == "STEP_SCALE" ) ? true : false; - return aPluginOperations->ImportSTEP( theFileName, anIsIgnoreUnits ); + return aPluginOperations->ImportSTEP( theFileName, anIsIgnoreUnits, false ); } //============================================================================= diff --git a/src/STEPPlugin/STEPPlugin_IImport.hxx b/src/STEPPlugin/STEPPlugin_IImport.hxx index 3b63fdfdc..f7630e4eb 100644 --- a/src/STEPPlugin/STEPPlugin_IImport.hxx +++ b/src/STEPPlugin/STEPPlugin_IImport.hxx @@ -22,8 +22,9 @@ #include "GEOM_Function.hxx" -#define IMPORTSTEP_ARG_FILENAME 1 -#define IMPORTSTEP_ARG_IGNORE_UNITS 2 +#define IMPORTSTEP_ARG_FILENAME 1 +#define IMPORTSTEP_ARG_IGNORE_UNITS 2 +#define IMPORTSTEP_ARG_CREATE_ASSEMBLIES 3 class STEPPlugin_IImport { @@ -41,6 +42,12 @@ public: bool GetIsIgnoreUnits() { return bool( _func->GetInteger( IMPORTSTEP_ARG_IGNORE_UNITS ) ); } + void SetIsCreateAssemblies( bool IsCreateAssemblies ) + { _func->SetInteger + ( IMPORTSTEP_ARG_CREATE_ASSEMBLIES, IsCreateAssemblies ? 1 : 0 ); } + bool GetIsCreateAssemblies() + { return ( _func->GetInteger( IMPORTSTEP_ARG_CREATE_ASSEMBLIES ) != 0 ); } + private: Handle(GEOM_Function) _func; }; diff --git a/src/STEPPlugin/STEPPlugin_IOperations.cxx b/src/STEPPlugin/STEPPlugin_IOperations.cxx index 72064e8e3..24f898aeb 100644 --- a/src/STEPPlugin/STEPPlugin_IOperations.cxx +++ b/src/STEPPlugin/STEPPlugin_IOperations.cxx @@ -167,8 +167,9 @@ void STEPPlugin_IOperations::ExportSTEP */ //============================================================================= Handle(TColStd_HSequenceOfTransient) -STEPPlugin_IOperations::ImportSTEP( const TCollection_AsciiString& theFileName, - const bool theIsIgnoreUnits ) +STEPPlugin_IOperations::ImportSTEP(const TCollection_AsciiString& theFileName, + const bool theIsIgnoreUnits, + const bool IsCreateAssemblies) { SetErrorCode(KO); if( theFileName.IsEmpty() ) return NULL; @@ -188,6 +189,7 @@ STEPPlugin_IOperations::ImportSTEP( const TCollection_AsciiString& theFileName, STEPPlugin_IImport aCI( aFunction ); aCI.SetFileName( theFileName ); aCI.SetIsIgnoreUnits( theIsIgnoreUnits ); + aCI.SetIsCreateAssemblies( IsCreateAssemblies ); //Perform the Import Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient; @@ -211,10 +213,10 @@ STEPPlugin_IOperations::ImportSTEP( const TCollection_AsciiString& theFileName, //Make a Python command GEOM::TPythonDump pd (aFunction); - if( theIsIgnoreUnits ) - pd << aSeq << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\", True)"; - else - pd << aSeq << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\")"; + pd << aSeq << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\", "; + pd << (theIsIgnoreUnits ? "True" : "False"); + pd << ", " << (IsCreateAssemblies ? "True" : "False"); + pd << ")"; SetErrorCode(OK); return aSeq; diff --git a/src/STEPPlugin/STEPPlugin_IOperations.hxx b/src/STEPPlugin/STEPPlugin_IOperations.hxx index 92b3f160e..90266d34b 100644 --- a/src/STEPPlugin/STEPPlugin_IOperations.hxx +++ b/src/STEPPlugin/STEPPlugin_IOperations.hxx @@ -57,8 +57,9 @@ public: void ExportSTEP( const Handle(GEOM_Object), const TCollection_AsciiString&, const LengthUnit ); - Handle(TColStd_HSequenceOfTransient) ImportSTEP( const TCollection_AsciiString&, - const bool ); + Handle(TColStd_HSequenceOfTransient) ImportSTEP(const TCollection_AsciiString&, + const bool, + const bool); TCollection_AsciiString ReadValue( const TCollection_AsciiString&, const TCollection_AsciiString& ); diff --git a/src/STEPPlugin/STEPPlugin_IOperations_i.cc b/src/STEPPlugin/STEPPlugin_IOperations_i.cc index fba3ce031..fa40dae0e 100644 --- a/src/STEPPlugin/STEPPlugin_IOperations_i.cc +++ b/src/STEPPlugin/STEPPlugin_IOperations_i.cc @@ -119,11 +119,16 @@ void STEPPlugin_IOperations_i::ExportSTEP(GEOM::GEOM_Object_ptr theOriginal, * \param theIsIgnoreUnits If True, file length units will be ignored (set to 'meter') * and result model will be scaled, if its units are not meters. * If False (default), file length units will be taken into account. + * \param IsCreateAssemblies If True, for each assembly compound is created + * in the result. If False Compounds that contain a + * single shape are eliminated from the result. * \return List of GEOM_Objects, containing the created shape and propagation groups. */ //============================================================================= -GEOM::ListOfGO* STEPPlugin_IOperations_i::ImportSTEP( const char* theFileName, - const bool theIsIgnoreUnits = false ) +GEOM::ListOfGO* STEPPlugin_IOperations_i::ImportSTEP + (const char *theFileName, + const bool theIsIgnoreUnits, + const bool IsCreateAssemblies) { GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO; @@ -131,7 +136,8 @@ GEOM::ListOfGO* STEPPlugin_IOperations_i::ImportSTEP( const char* theFileName, GetOperations()->SetNotDone(); //Import the shape from the file - Handle(TColStd_HSequenceOfTransient) aHSeq = GetOperations()->ImportSTEP( theFileName, theIsIgnoreUnits ); + Handle(TColStd_HSequenceOfTransient) aHSeq = GetOperations()->ImportSTEP + (theFileName, theIsIgnoreUnits, IsCreateAssemblies); if( !GetOperations()->IsDone() || aHSeq.IsNull() ) return aSeq._retn(); diff --git a/src/STEPPlugin/STEPPlugin_IOperations_i.hh b/src/STEPPlugin/STEPPlugin_IOperations_i.hh index 16e000909..4faa4128c 100644 --- a/src/STEPPlugin/STEPPlugin_IOperations_i.hh +++ b/src/STEPPlugin/STEPPlugin_IOperations_i.hh @@ -45,7 +45,7 @@ public: void ExportSTEP( GEOM::GEOM_Object_ptr, const char*, GEOM::length_unit ); - GEOM::ListOfGO* ImportSTEP( const char*, const bool ); + GEOM::ListOfGO* ImportSTEP( const char*, const bool, const bool ); char* ReadValue( const char*, const char* ); STEPPlugin_IOperations* GetOperations(); diff --git a/src/STEPPlugin/STEPPlugin_ImportDlg.cxx b/src/STEPPlugin/STEPPlugin_ImportDlg.cxx new file mode 100644 index 000000000..de6cb2169 --- /dev/null +++ b/src/STEPPlugin/STEPPlugin_ImportDlg.cxx @@ -0,0 +1,94 @@ +// Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "STEPPlugin_ImportDlg.h" + +#include +#include +#include + +//============================================================================= +// Constructor +//============================================================================= +STEPPlugin_ImportDlg::STEPPlugin_ImportDlg(QWidget *parent) + : SUIT_FileDlg (parent, true, true, true), + myCheckBox (0) +{ + myCheckBox = new QCheckBox(tr("STEP_CREATE_ASSEMBLIES"), this); + + myCheckBox->setChecked(true); + + layout()->addWidget(myCheckBox); +} + +//============================================================================= +// Destructor +//============================================================================= +STEPPlugin_ImportDlg::~STEPPlugin_ImportDlg() +{ +} + +//============================================================================= +// IsCreateAssemblies +//============================================================================= +bool STEPPlugin_ImportDlg::IsCreateAssemblies() const +{ + return myCheckBox->isChecked(); +} + +//============================================================================= +// getOpenFileNames +//============================================================================= +QStringList STEPPlugin_ImportDlg::getOpenFileNames + (const QString &theInitial, + const QString &theFilters, + const QString &theCaption, + QWidget *theParent, + bool &IsCreateAssemblies) +{ + STEPPlugin_ImportDlg anImpDlg(theParent); + QStringList aFilters = theFilters.split(";;", QString::SkipEmptyParts); + + anImpDlg.setFileMode(ExistingFiles); + + if (aFilters.isEmpty()) { + anImpDlg.setFilter(tr("ALL_FILES_FILTER")); // All files (*) + } else { + anImpDlg.setFilters(aFilters); + } + + if (!theCaption.isEmpty()) { + anImpDlg.setWindowTitle(theCaption); + } + + if (!theInitial.isEmpty()) { + anImpDlg.processPath(theInitial); + } + + QStringList aFileNames; + + if (anImpDlg.exec() == QDialog::Accepted) { + aFileNames = anImpDlg.selectedFiles(); + IsCreateAssemblies = anImpDlg.IsCreateAssemblies(); + } + + QApplication::processEvents(); + + return aFileNames; +} diff --git a/src/STEPPlugin/STEPPlugin_ImportDlg.h b/src/STEPPlugin/STEPPlugin_ImportDlg.h new file mode 100644 index 000000000..32f75d3e5 --- /dev/null +++ b/src/STEPPlugin/STEPPlugin_ImportDlg.h @@ -0,0 +1,52 @@ +// Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef STEPPlugin_ImportDlg_H +#define STEPPlugin_ImportDlg_H + +#include +#include +#include CORBA_CLIENT_HEADER(STEPPlugin) + +class QCheckBox; + +class STEPPlugin_ImportDlg: public SUIT_FileDlg +{ + Q_OBJECT + +public: + + STEPPlugin_ImportDlg(QWidget *parent); + ~STEPPlugin_ImportDlg(); + + bool IsCreateAssemblies() const; + + static QStringList getOpenFileNames (const QString &theInitial, + const QString &theFilters, + const QString &theCaption, + QWidget *theParent, + bool &IsCreateAssemblies); + +private: + + QCheckBox *myCheckBox; + +}; + +#endif // STEPPlugin_ImportDlg_H diff --git a/src/STEPPlugin/STEPPlugin_ImportDriver.cxx b/src/STEPPlugin/STEPPlugin_ImportDriver.cxx index 961dd77be..1cf37959d 100644 --- a/src/STEPPlugin/STEPPlugin_ImportDriver.cxx +++ b/src/STEPPlugin/STEPPlugin_ImportDriver.cxx @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,11 @@ #include #include #include +#include #include +#include +#include +#include #include #include #include @@ -139,22 +144,227 @@ namespace return aResult; } + //============================================================================= + /*! + * GetAllParents() + */ + //============================================================================= + + Standard_Boolean GetAllParents(const TopoDS_Shape &theShape, + const TopoDS_Shape &theSubShape, + TopTools_ListOfShape &theParents) + { + const TopAbs_ShapeEnum aSubShType = theSubShape.ShapeType(); + Standard_Boolean aResult = Standard_False; + + if (theShape.ShapeType() >= aSubShType) { + return aResult; // NULL shape + } + + TopoDS_Iterator anIt(theShape); + TopTools_MapOfShape aMapFence; + + for (; anIt.More(); anIt.Next()) { + const TopoDS_Shape &aSubShape = anIt.Value(); + + if (aMapFence.Add(aSubShape)) { + if (theSubShape.IsSame(aSubShape)) { + // The sub-shape is found. theShape is its parent. + theParents.Append(theShape); + aResult = Standard_True; + break; + } + + if (aSubShape.ShapeType() < aSubShType) { + if (GetAllParents(aSubShape, theSubShape, theParents)) { + // The sub-shape is found. + theParents.Append(theShape); + aResult = Standard_True; + break; + } + } + } + } + + return aResult; + } + + //============================================================================= + /*! + * BuildModifiedShape() + */ + //============================================================================= + + TopoDS_Shape BuildModifiedShape + (const TopoDS_Shape &theShape, + TopTools_DataMapOfShapeShape &theMapModified) + { + // Check if the shape is modified. + TopoDS_Shape aFwdShape = theShape.Oriented(TopAbs_FORWARD); + TopoDS_Iterator anIt(aFwdShape); + Standard_Boolean isModified = Standard_False; + + for (; anIt.More(); anIt.Next()) { + if (theMapModified.IsBound(anIt.Value())) { + isModified = Standard_True; + break; + } + } + + TopoDS_Shape aResult; + + if (isModified) { + BRep_Builder aBuilder; + + aResult = aFwdShape.EmptyCopied(); + + for (anIt.Initialize(aFwdShape); anIt.More(); anIt.Next()) { + const TopoDS_Shape &aSubShape = anIt.Value(); + + if (theMapModified.IsBound(aSubShape)) { + TopoDS_Shape aModifSubShape = theMapModified.Find(aSubShape); + + if (aModifSubShape.IsNull()) { + // Recursively compute the sub-shape. + aModifSubShape = BuildModifiedShape(aSubShape, theMapModified); + } + + aBuilder.Add(aResult, aModifSubShape); + } else { + aBuilder.Add(aResult, aSubShape); + } + } + + // Set the result shape orienation. + aResult.Orientation(theShape.Orientation()); + theMapModified.Bind(theShape, aResult); + } else { + aResult = theShape; + } + + return aResult; + } + + //============================================================================= + /*! + * CreateAssemblies() + */ + //============================================================================= + + TopoDS_Shape CreateAssemblies + (const STEPControl_Reader &theReader, + const TopoDS_Shape &theShape, + TopTools_DataMapOfShapeShape &theMapShapeAssembly) + { + TopoDS_Shape aResult = theShape; + Handle(XSControl_TransferReader) aTR = theReader.WS()->TransferReader(); + TopTools_ListOfShape aListAssemblies; + + if (!aTR.IsNull()) { + Handle(Interface_InterfaceModel) aModel = theReader.WS()->Model(); + Handle(Transfer_TransientProcess) aTP = aTR->TransientProcess(); + Standard_Integer aNbEntities = aModel->NbEntities(); + Standard_Integer i; + Handle(Standard_Type) aNAUOType = + STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence); + + for (i = 1; i <= aNbEntities; i++) { + Handle(Standard_Transient) anEnti = aModel->Value(i); + + if (anEnti->IsKind(aNAUOType)) { + // This is an assembly. Find target shape + TopoDS_Shape aShape = GetShape(anEnti, aTP); + + if (aShape.IsNull()) { + continue; + } + + if (aShape.ShapeType() != TopAbs_COMPOUND) { + aListAssemblies.Append(aShape); + } + } + } + } + + // Create assemblies. + if (!aListAssemblies.IsEmpty()) { + TopTools_ListIteratorOfListOfShape anIter(aListAssemblies); + BRep_Builder aBuilder; + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aShape = anIter.Value(); + TopTools_ListOfShape aParents; + + if (GetAllParents(theShape, aShape, aParents) && + aParents.First().ShapeType() == TopAbs_COMPOUND) { + TopoDS_Compound aComp; + TopTools_ListIteratorOfListOfShape aParentIter(aParents); + + // Fill theMapShapeAssembly. + for (; aParentIter.More(); aParentIter.Next()) { + theMapShapeAssembly.Bind(aParentIter.Value(), TopoDS_Shape()); + } + + aBuilder.MakeCompound(aComp); + aBuilder.Add(aComp, aShape); + theMapShapeAssembly.Bind(aShape, aComp); + } + } + + // Build a new shape. + aResult = BuildModifiedShape(theShape, theMapShapeAssembly); + } + + return aResult; + } + //============================================================================= /*! * StoreName() */ //============================================================================= - void StoreName( const Handle(Standard_Transient) &theEnti, - const TopTools_IndexedMapOfShape &theIndices, - const Handle(Transfer_TransientProcess) &theTP, - const TDF_Label &theShapeLabel) + void StoreName(const Handle(Standard_Transient) &theEnti, + const TopTools_IndexedMapOfShape &theIndices, + const Handle(XSControl_WorkSession) &theWS, + const Handle(Transfer_TransientProcess) &theTP, + const TDF_Label &theShapeLabel, + TopTools_DataMapOfShapeShape &theMapShapeAssembly) { Handle(TCollection_HAsciiString) aName; if (theEnti->IsKind(STANDARD_TYPE(StepShape_TopologicalRepresentationItem)) || theEnti->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) { aName = Handle(StepRepr_RepresentationItem)::DownCast(theEnti)->Name(); + } else if (theEnti->IsKind(STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence))) { + Handle(StepRepr_NextAssemblyUsageOccurrence) aNAUO = + Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(theEnti); + + Interface_EntityIterator aSubs = theWS->Graph().Sharings(aNAUO); + + for (aSubs.Start(); aSubs.More(); aSubs.Next()) { + Handle(StepRepr_ProductDefinitionShape) aPDS = + Handle(StepRepr_ProductDefinitionShape)::DownCast(aSubs.Value()); + + if(aPDS.IsNull()) { + continue; + } + + Handle(StepBasic_ProductDefinitionRelationship) aPDR = + aPDS->Definition().ProductDefinitionRelationship(); + + if (aPDR.IsNull()) { + continue; + } + + if (aPDR->HasDescription() && aPDR->Description()->Length() >0) { + aName = aPDR->Description(); + } else if (!aPDR->Name().IsNull() && aPDR->Name()->Length() >0 ) { + aName = aPDR->Name(); + } else if (!aPDR->Id().IsNull()) { + aName = aPDR->Id(); + } + } } else { Handle(StepBasic_ProductDefinition) PD = Handle(StepBasic_ProductDefinition)::DownCast(theEnti); @@ -198,6 +408,10 @@ namespace // find target shape TopoDS_Shape S = GetShape(theEnti, theTP); + if (theMapShapeAssembly.IsBound(S)) { + S = theMapShapeAssembly.Find(S); + } + if (S.IsNull()) { return; } @@ -392,6 +606,7 @@ Standard_Integer STEPPlugin_ImportDriver::Execute( TFunction_Logbook& log ) cons TCollection_AsciiString aFileName = aData.GetFileName().ToCString(); bool anIsIgnoreUnits = aData.GetIsIgnoreUnits(); + bool isCreateAssemblies = aData.GetIsCreateAssemblies(); TDF_Label aShapeLabel = aFunction->GetNamingEntry(); MESSAGE("Import STEP from file " << aFileName.ToCString() ); @@ -439,48 +654,91 @@ Standard_Integer STEPPlugin_ImportDriver::Execute( TFunction_Logbook& log ) cons aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity); // Root transfers - Standard_Integer nbr = aReader.NbRootsForTransfer(); + Standard_Integer aNbRoots = aReader.NbRootsForTransfer(); + Standard_Integer i; + aReader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity); - for (Standard_Integer n = 1; n <= nbr; n++) { - Standard_Boolean ok = aReader.TransferRoot(n); - // Collecting resulting entities - Standard_Integer nbs = aReader.NbShapes(); - if (!ok || nbs == 0) - continue; // skip empty root + for (i = 1; i <= aNbRoots; i++) { + aReader.TransferRoot(i); + } - // For a single entity - else if (nbr == 1 && nbs == 1) { - aResShape = aReader.Shape(1); - if (aResShape.ShapeType() == TopAbs_COMPOUND) { - int nbSub1 = 0; - TopoDS_Shape currShape; - TopoDS_Iterator It (aResShape, Standard_True, Standard_True); - for (; It.More(); It.Next()) { - nbSub1++; - currShape = It.Value(); - } - if (nbSub1 == 1) - aResShape = currShape; - } - break; - } + // Create result shape + const Standard_Integer aNbShapes = aReader.NbShapes(); + TopTools_ListOfShape aListResShapes; - for (Standard_Integer i = 1; i <= nbs; i++) { + if (isCreateAssemblies) { + for (i = 1; i <= aNbShapes; i++) { TopoDS_Shape aShape = aReader.Shape(i); - if (aShape.IsNull()) + + if (aShape.IsNull()) { continue; - else - B.Add(compound, aShape); + } + + aListResShapes.Append(aShape); + } + } else { + for (i = 1; i <= aNbShapes; i++) { + TopoDS_Shape aShape = aReader.Shape(i); + + if (aShape.IsNull()) { + continue; + } + + if (aShape.ShapeType() == TopAbs_COMPOUND) { + int aNbSub = 0; + TopoDS_Shape aSubShape; + TopoDS_Iterator anIt (aShape, Standard_True, Standard_True); + + for (; anIt.More(); anIt.Next()) { + aNbSub++; + aSubShape = anIt.Value(); + } + + if (aNbSub == 1) { + // Use the single sub-shape + aListResShapes.Append(aSubShape); + } else if (aNbSub > 1) { + // Use the shape + aListResShapes.Append(aShape); + } + } } } - if( aResShape.IsNull() ) - aResShape = compound; + + // Construct result shape. + if (!aListResShapes.IsEmpty()) { + if (aListResShapes.Extent() == 1) { + // Use the single shape. + aResShape = aListResShapes.First(); + } else { + // Make a compound of result shapes. + TopTools_ListIteratorOfListOfShape anIt(aListResShapes); + + for (; anIt.More(); anIt.Next()) { + B.Add(compound, anIt.Value()); + } + + aResShape = compound; + } + } + + if( aResShape.IsNull() ) { + StdFail_NotDone::Raise("Null result shape"); + return 0; + } // Check if any BRep entity has been read, there must be at least a vertex if ( !TopExp_Explorer( aResShape, TopAbs_VERTEX ).More() ) StdFail_NotDone::Raise( "No geometrical data in the imported file." ); + // Create assemblies in the shape, if they are not created yet. + TopTools_DataMapOfShapeShape aMapShapeAssembly; + + if (isCreateAssemblies) { + aResShape = CreateAssemblies(aReader, aResShape, aMapShapeAssembly); + } + // BEGIN: Store names and materials of sub-shapes from file TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(aResShape, anIndices); @@ -496,7 +754,8 @@ Standard_Integer STEPPlugin_ImportDriver::Execute( TFunction_Logbook& log ) cons Handle(Standard_Transient) enti = Model->Value(ie); // Store names. - StoreName(enti, anIndices, TP, aShapeLabel); + StoreName(enti, anIndices, aReader.WS(), + TP, aShapeLabel, aMapShapeAssembly); // Store materials. StoreMaterial(enti, anIndices, TP, aShapeLabel); @@ -575,6 +834,7 @@ GetCreationInformation( std::string& theOperationName, AddParam( theParams, "File name", aCI.GetFileName() ); if( aCI.GetIsIgnoreUnits() ) AddParam( theParams, "Format", "STEP_SCALE" ); + AddParam( theParams, "Create Assemblies", aCI.GetIsCreateAssemblies() ); break; default: return false; diff --git a/src/STEPPlugin/STEPPlugin_msg_en.ts b/src/STEPPlugin/STEPPlugin_msg_en.ts index 47d15c8f8..606569a0d 100644 --- a/src/STEPPlugin/STEPPlugin_msg_en.ts +++ b/src/STEPPlugin/STEPPlugin_msg_en.ts @@ -95,4 +95,11 @@ Ignoring units will cause model scaling (as dimensions are supposed to be specif microinch + + STEPPlugin_ImportDlg + + STEP_CREATE_ASSEMBLIES + Create assemblies + + From 80b714c3bbca8fa3acb9b7e65b436c6c86ff9261 Mon Sep 17 00:00:00 2001 From: skv Date: Wed, 17 Feb 2016 11:01:45 +0300 Subject: [PATCH 48/63] 0023216: correct treatment of blank assembly names --- src/STEPPlugin/STEPPlugin_ImportDriver.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/STEPPlugin/STEPPlugin_ImportDriver.cxx b/src/STEPPlugin/STEPPlugin_ImportDriver.cxx index 1cf37959d..4dd581f99 100644 --- a/src/STEPPlugin/STEPPlugin_ImportDriver.cxx +++ b/src/STEPPlugin/STEPPlugin_ImportDriver.cxx @@ -357,9 +357,9 @@ namespace continue; } - if (aPDR->HasDescription() && aPDR->Description()->Length() >0) { + if (aPDR->HasDescription() && aPDR->Description()->UsefullLength() >0) { aName = aPDR->Description(); - } else if (!aPDR->Name().IsNull() && aPDR->Name()->Length() >0 ) { + } else if (!aPDR->Name().IsNull() && aPDR->Name()->UsefullLength() >0 ) { aName = aPDR->Name(); } else if (!aPDR->Id().IsNull()) { aName = aPDR->Id(); From 1f2a7c5f515562c29eb0719e78043c1d9ef93024 Mon Sep 17 00:00:00 2001 From: skv Date: Sat, 20 Feb 2016 15:13:14 +0300 Subject: [PATCH 49/63] 0053082: Script "GEOM_usinggeom" failed --- src/STEPPlugin/STEPPlugin_ImportDriver.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/STEPPlugin/STEPPlugin_ImportDriver.cxx b/src/STEPPlugin/STEPPlugin_ImportDriver.cxx index 4dd581f99..254f95f1c 100644 --- a/src/STEPPlugin/STEPPlugin_ImportDriver.cxx +++ b/src/STEPPlugin/STEPPlugin_ImportDriver.cxx @@ -702,6 +702,9 @@ Standard_Integer STEPPlugin_ImportDriver::Execute( TFunction_Logbook& log ) cons // Use the shape aListResShapes.Append(aShape); } + } else { + // Use the shape itself + aListResShapes.Append(aShape); } } } From 1125dd97347a890f0a6dc0e3bfb7567298d30db0 Mon Sep 17 00:00:00 2001 From: vsr Date: Fri, 11 Mar 2016 12:02:33 +0300 Subject: [PATCH 50/63] XAOPlugin Python API improvements - Add missing python doc - Enable auto-publishing for ImportXAO operation --- src/GEOM_SWIG/XAOPluginBuilder.py | 53 +++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/GEOM_SWIG/XAOPluginBuilder.py b/src/GEOM_SWIG/XAOPluginBuilder.py index b30467f0e..ca90f8baa 100644 --- a/src/GEOM_SWIG/XAOPluginBuilder.py +++ b/src/GEOM_SWIG/XAOPluginBuilder.py @@ -31,12 +31,25 @@ def GetXAOPluginOperations(self): # @param shape The shape to export # @param groups The list of groups to export # @param fields The list of fields to export -# @param author The author of the export +# @param author The author of the file # @param fileName The name of the file to export -# @return boolean +# @return True if operation is successful or False otherwise # # @ingroup l2_import_export def ExportXAO(self, shape, groups, fields, author, fileName): + """ + Export a shape to XAO format + + Parameters: + shape The shape to export + groups The list of groups to export + fields The list of fields to export + author The author of the file + fileName The name of the file to export + + Returns: + True if operation is successful or False otherwise + """ from salome.geom.geomBuilder import RaiseIfFailed anOp = GetXAOPluginOperations(self) res = anOp.ExportXAO(shape, groups, fields, author, fileName) @@ -45,17 +58,39 @@ def ExportXAO(self, shape, groups, fields, author, fileName): ## Import a shape from XAO format # @param fileName The name of the file to import -# @return tuple (res, shape, subShapes, groups, fields) -# res Flag indicating if the import was successful -# shape The imported shape -# subShapes The list of imported subShapes -# groups The list of imported groups -# fields The list of imported fields +# @param theName Object name; when specified, this parameter is used +# for result publication in the study. Otherwise, if automatic +# publication is switched on, default value is used for result name. +# +# @return tuple (\a res, \a shape, \a subShapes, \a groups, \a fields) +# \a res Flag indicating if the import was successful +# \a shape The imported shape +# \a subShapes The list of imported subShapes +# \a groups The list of imported groups +# \a fields The list of imported fields # # @ingroup l2_import_export -def ImportXAO(self, fileName): +def ImportXAO(self, fileName, theName=None): + """ + Import a shape from XAO format + + Parameters: + fileName The name of the file to import + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + A tuple (res, shape, subShapes, groups, fields): + - res: Flag indicating if the import was successful + - shape: The imported shape + - subShapes: The list of imported subShapes + - groups: The list of imported groups + - fields: The list of imported fields + """ from salome.geom.geomBuilder import RaiseIfFailed anOp = GetXAOPluginOperations(self) res = anOp.ImportXAO(fileName) RaiseIfFailed("ImportXAO", anOp) + self._autoPublish(res[1], theName, "imported") return res From 45914b2b1521ad481380f9ae99152b7d9fff52db Mon Sep 17 00:00:00 2001 From: vsr Date: Fri, 11 Mar 2016 12:03:17 +0300 Subject: [PATCH 51/63] 0023252: [CEA 1780] GEOM : Error on "make test" when SAMPLES module is missing --- doc/salome/examples/free_boundaries.py | 99 +++++-------------- doc/salome/examples/import_export.py | 91 +++++++++++------ doc/salome/examples/viewing_geom_objs_ex04.py | 3 +- resources/CMakeLists.txt | 7 ++ resources/texture1.dat | 8 ++ resources/texture2.dat | 8 ++ resources/texture3.dat | 8 ++ 7 files changed, 118 insertions(+), 106 deletions(-) create mode 100755 resources/texture1.dat create mode 100755 resources/texture2.dat create mode 100755 resources/texture3.dat diff --git a/doc/salome/examples/free_boundaries.py b/doc/salome/examples/free_boundaries.py index d36bbbbf7..8fe0d475b 100644 --- a/doc/salome/examples/free_boundaries.py +++ b/doc/salome/examples/free_boundaries.py @@ -1,82 +1,35 @@ # Check Free Boundaries -import os import salome salome.salome_init() -import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New(salome.myStudy) -gg = salome.ImportComponentGUI("GEOM") -# create boxes -box1 = geompy.MakeBox(0,0,0,100,50,100) -box2 = geompy.MakeBox(100,0,0,250,50,100) +# create a shape +box1 = geompy.MakeBox(0, 0, 0, 100, 100, 100) +box2 = geompy.MakeBox(20, 20, -20, 80, 80, 120) +cut = geompy.MakeCut(box1, box2) +sid = geompy.addToStudy(cut, "Shape") -# make a compound -compound = geompy.MakeCompound([box1, box2]) +# get all faces +faces = geompy.SubShapeAllSortedCentres(cut, geompy.ShapeType["FACE"]) -# import from *.brep -ImportFromBREP = geompy.ImportBREP(os.getenv("DATA_DIR")+"/Shapes/Brep/flight_solid.brep") - -# get a face -faces = geompy.SubShapeAllSortedCentres(ImportFromBREP, geompy.ShapeType["FACE"]) - -# get the free boundary for face 32 -Res = geompy.GetFreeBoundary(faces[32]) -isSuccess = Res[0] -ClosedWires = Res[1] -OpenWires = Res[2] - -if isSuccess == 1 : - print "Checking free boudaries is OK." -else : - print "Checking free boudaries is KO!" -print "len(ClosedWires) = ", len(ClosedWires) - -i = 0 -for wire in ClosedWires : - wire_name = "Face 32 -> Close wires : WIRE %d"%(i+1) - geompy.addToStudy(ClosedWires[i], wire_name) - if i < len(ClosedWires) : - i = i+ 1 - -print "len(OpenWires) = ", len(OpenWires) - -i = 0 -for wire in OpenWires : - wire_name = "Face 32 -> Open wires : WIRE %d"%(i+1) - geompy.addToStudy(OpenWires[i], wire_name) - if i < len(OpenWires) : - i = i+ 1 - -# get the free boundary for face 41 -Res = geompy.GetFreeBoundary(faces[41]) -isSuccess = Res[0] -ClosedWires = Res[1] -OpenWires = Res[2] - -if isSuccess == 1 : - print "Checking free boudaries is OK." -else : - print "Checking free boudaries is KO!" -print "len(ClosedWires) = ", len(ClosedWires) - -i = 0 -for wire in ClosedWires : - wire_name = "Face 41 -> Close wires : WIRE %d"%(i+1) - geompy.addToStudy(ClosedWires[i], wire_name) - if i < len(ClosedWires) : - i = i+ 1 - -print "len(OpenWires) = ", len(OpenWires) - -i = 0 -for wire in OpenWires : - wire_name = "Face 41 -> Open wires : WIRE %d"%(i+1) - geompy.addToStudy(OpenWires[i], wire_name) - if i < len(OpenWires) : - i = i+ 1 - -# add the imported object to the study -id_ImportFromBREP = geompy.addToStudy(ImportFromBREP, "ImportFromBREP") -salome.sg.updateObjBrowser(1) +# for each face, get free boundaries +for fi in range(len(faces)): + fid = geompy.addToStudyInFather(cut, faces[fi], "Face %d" % (fi+1)) + isSuccess, closedWires, openWires = geompy.GetFreeBoundary(faces[fi]) + if isSuccess: + print "Check free boudaries in face %d: OK" % (fi+1) + print "-- Nb of closed boundaries = %d" % len(closedWires) + for wi in range(len(closedWires)): + wid = geompy.addToStudyInFather(faces[fi], closedWires[wi], "Closed wire %d" % (wi+1)) + pass + print "-- Nb of open boundaries = %d" % len(openWires) + for wi in range(len(openWires)): + wid = geompy.addToStudyInFather(faces[fi], openWires[wi], "Open wire %d" % (wi+1)) + pass + pass + else: + print "Check free boudaries in face %d: KO" % (fi+1) + pass + pass diff --git a/doc/salome/examples/import_export.py b/doc/salome/examples/import_export.py index 3b5f7df60..e7ed69c37 100644 --- a/doc/salome/examples/import_export.py +++ b/doc/salome/examples/import_export.py @@ -6,38 +6,65 @@ import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New(salome.myStudy) -# Example of import from IGES using various formats +import tempfile, os -# get a path to SAMPLES_SRC -import os -thePath = os.getenv("DATA_DIR") -# create filenames -theFileName1 = thePath + "/Shapes/Iges/boite-3Dipsos_m.igs" -theFileName2 = thePath + "/Shapes/Iges/boite-3Dipsos_mm.igs" -#print "thePath = ", thePath +# create a sphere +sphere = geompy.MakeSphereR(100) -# get units from files -UnitName1 = geompy.GetIGESUnit(theFileName1) -UnitName2 = geompy.GetIGESUnit(theFileName2) -print "UnitName1 = ", UnitName1 -print "UnitName2 = ", UnitName2 +tmpdir = tempfile.mkdtemp() -# import shapes -Shape1 = geompy.ImportIGES(theFileName1) -Shape2 = geompy.ImportIGES(theFileName2) -Shape3 = geompy.ImportIGES(theFileName2, True) -[Xmin1,Xmax1, Ymin1,Ymax1, Zmin1,Zmax1] = geompy.BoundingBox(Shape1) -[Xmin2,Xmax2, Ymin2,Ymax2, Zmin2,Zmax2] = geompy.BoundingBox(Shape2) -[Xmin3,Xmax3, Ymin3,Ymax3, Zmin3,Zmax3] = geompy.BoundingBox(Shape3) -geompy.addToStudy(Shape1, "3Dipsos_m") -geompy.addToStudy(Shape2, "3Dipsos_mm") -geompy.addToStudy(Shape3, "3Dipsos_mm_scaled") -d1 = (Xmax1-Xmin1)*(Xmax1-Xmin1) + (Ymax1-Ymin1)*(Ymax1-Ymin1) + (Zmax1-Zmin1)*(Zmax1-Zmin1) -d2 = (Xmax2-Xmin2)*(Xmax2-Xmin2) + (Ymax2-Ymin2)*(Ymax2-Ymin2) + (Zmax2-Zmin2)*(Zmax2-Zmin2) -d3 = (Xmax3-Xmin3)*(Xmax3-Xmin3) + (Ymax3-Ymin3)*(Ymax3-Ymin3) + (Zmax3-Zmin3)*(Zmax3-Zmin3) -import math -dd32 = math.sqrt(d3/d2) -dd12 = math.sqrt(d1/d2) -dd31 = math.sqrt(d3/d1) -# values dd31, dd12 and dd31 can be using for checking -print "dd32 = ",dd32," dd12 = ",dd12," dd31 = ",dd31 +# export sphere to the BREP file +f_brep = os.path.join(tmpdir, "sphere.brep") +geompy.ExportBREP(sphere, f_brep) + +# export sphere to the IGES v5.3 file +f_iges = os.path.join(tmpdir, "sphere.iges") +geompy.ExportIGES(sphere, f_iges, "5.3") + +# export sphere to the STEP file, using millimeters as length units +f_step = os.path.join(tmpdir, "sphere.step") +geompy.ExportSTEP(sphere, f_step, GEOM.LU_MILLIMETER) + +# export sphere to the binary STL file, with default deflection coefficient +f_stl1 = os.path.join(tmpdir, "sphere1.stl") +geompy.ExportSTL(sphere, f_stl1, False) + +# export sphere to the ASCII STL file, with custom deflection coefficient +f_stl2 = os.path.join(tmpdir, "sphere2.stl") +geompy.ExportSTL(sphere, f_stl2, True, 0.1) + +# export sphere to the VTK file, with default deflection coefficient +f_vtk1 = os.path.join(tmpdir, "sphere1.vtk") +geompy.ExportVTK(sphere, f_vtk1) + +# export sphere to the VTK file, with custom deflection coefficient +f_vtk2 = os.path.join(tmpdir, "sphere2.vtk") +geompy.ExportVTK(sphere, f_vtk2, 0.1) + +# export sphere to the XAO file +f_xao = os.path.join(tmpdir, "sphere.xao") +geompy.ExportXAO(sphere, [], [], "author", f_xao) + +# import BREP file +sphere_brep = geompy.ImportBREP(f_brep) + +# import IGES file +sphere_iges = geompy.ImportIGES(f_iges) + +# import STEP file, taking units into account +sphere_step1 = geompy.ImportSTEP(f_step) + +# import STEP file, ignoring units (result is scaled) +sphere_step2 = geompy.ImportSTEP(f_step, True) + +# import STL files +sphere_stl1 = geompy.ImportSTL(f_stl1) +sphere_stl2 = geompy.ImportSTL(f_stl2) + +# import XAO file +ok, sphere_xao, sub_shapes, groups, fields = geompy.ImportXAO(f_xao) + +# clean up +for f in f_brep, f_iges, f_step, f_stl1, f_stl2, f_vtk1, f_vtk2, f_xao: + os.remove(f) +os.rmdir(tmpdir) diff --git a/doc/salome/examples/viewing_geom_objs_ex04.py b/doc/salome/examples/viewing_geom_objs_ex04.py index 98ef64526..093fdfbe1 100644 --- a/doc/salome/examples/viewing_geom_objs_ex04.py +++ b/doc/salome/examples/viewing_geom_objs_ex04.py @@ -7,7 +7,8 @@ import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New(salome.myStudy) -texture = geompy.LoadTexture(os.getenv("DATA_DIR")+"/Textures/texture1.dat") +texture_file = os.path.join(os.getenv("GEOM_ROOT_DIR"), "share", "salome", "resources", "geom", "textures", "texture1.dat") +texture = geompy.LoadTexture(texture_file) v1 = geompy.MakeVertex(0, 0, 0) v2 = geompy.MakeVertex(100, 0, 0) diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 3d47d93ed..b08b1d5b9 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -301,6 +301,13 @@ SET( _res_files ) INSTALL(FILES ${_res_files} DESTINATION ${SALOME_GEOM_INSTALL_RES_DATA}) +SET( _texture_files + texture1.dat + texture2.dat + texture3.dat +) +INSTALL(FILES ${_texture_files} DESTINATION ${SALOME_GEOM_INSTALL_RES_DATA}/textures) + SALOME_CONFIGURE_FILE(GEOMCatalog.xml.in GEOMCatalog.xml INSTALL ${SALOME_GEOM_INSTALL_RES_DATA}) SALOME_CONFIGURE_FILE(SalomeApp.xml.in SalomeApp.xml INSTALL ${SALOME_GEOM_INSTALL_RES_DATA}) SALOME_CONFIGURE_FILE(Plugin.in Plugin INSTALL ${SALOME_GEOM_INSTALL_RES_DATA}) diff --git a/resources/texture1.dat b/resources/texture1.dat new file mode 100755 index 000000000..7c37a0a53 --- /dev/null +++ b/resources/texture1.dat @@ -0,0 +1,8 @@ +11111111 +10000001 +10011001 +10111101 +10111101 +10011001 +10000001 +11111111 \ No newline at end of file diff --git a/resources/texture2.dat b/resources/texture2.dat new file mode 100755 index 000000000..43f3ea0af --- /dev/null +++ b/resources/texture2.dat @@ -0,0 +1,8 @@ +00111100 +00111100 +11111111 +11111111 +11111111 +11111111 +00111100 +00111100 \ No newline at end of file diff --git a/resources/texture3.dat b/resources/texture3.dat new file mode 100755 index 000000000..3ea373329 --- /dev/null +++ b/resources/texture3.dat @@ -0,0 +1,8 @@ +00111100 +00000000 +10111101 +10111101 +10111101 +10111101 +00000000 +00111100 \ No newline at end of file From ef5ed77d707e6ad392684ff83d213296781ffd07 Mon Sep 17 00:00:00 2001 From: skv Date: Fri, 13 Nov 2015 09:21:54 +0300 Subject: [PATCH 52/63] 0023197: [CEA] Extract and rebuild --- doc/salome/gui/GEOM/CMakeLists.txt | 1 + doc/salome/gui/GEOM/images/extract_init.png | Bin 0 -> 4948 bytes .../gui/GEOM/images/extract_rebuild.png | Bin 0 -> 39127 bytes doc/salome/gui/GEOM/images/extract_result.png | Bin 0 -> 2941 bytes .../gui/GEOM/input/extract_and_rebuild.doc | 82 + doc/salome/gui/GEOM/input/related_docs.doc | 2 + .../gui/GEOM/input/transforming_geom_objs.doc | 2 + doc/salome/gui/GEOM/input/tui_test_all.doc | 3 + .../gui/GEOM/static/ExtractAndRebuild.pdf | Bin 0 -> 51279 bytes idl/GEOM_Gen.idl | 37 + resources/CMakeLists.txt | 1 + resources/extract.png | Bin 0 -> 1155 bytes src/GEOMAlgo/CMakeLists.txt | 2 + src/GEOMAlgo/GEOMAlgo_Extractor.cxx | 1429 +++++++++++++++++ src/GEOMAlgo/GEOMAlgo_Extractor.hxx | 363 +++++ src/GEOMGUI/GEOM_images.ts | 8 + src/GEOMGUI/GEOM_msg_en.ts | 75 + src/GEOMGUI/GEOM_msg_fr.ts | 75 + src/GEOMGUI/GEOM_msg_ja.ts | 75 + src/GEOMGUI/GeometryGUI.cxx | 4 + src/GEOMGUI/GeometryGUI_Operations.h | 1 + src/GEOMImpl/CMakeLists.txt | 1 + src/GEOMImpl/GEOMImpl_IExtract.hxx | 73 + src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 102 ++ src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 34 + src/GEOMImpl/GEOMImpl_ShapeDriver.cxx | 135 ++ src/GEOMImpl/GEOMImpl_Types.hxx | 3 + src/GEOM_I/GEOM_IShapesOperations_i.cc | 95 ++ src/GEOM_I/GEOM_IShapesOperations_i.hh | 5 + src/GEOM_SWIG/GEOM_TestAll.py | 5 + src/GEOM_SWIG/geomBuilder.py | 29 + src/OperationGUI/CMakeLists.txt | 3 + src/OperationGUI/OperationGUI.cxx | 2 + .../OperationGUI_ExtractionDlg.cxx | 1324 +++++++++++++++ src/OperationGUI/OperationGUI_ExtractionDlg.h | 115 ++ 35 files changed, 4086 insertions(+) create mode 100644 doc/salome/gui/GEOM/images/extract_init.png create mode 100644 doc/salome/gui/GEOM/images/extract_rebuild.png create mode 100644 doc/salome/gui/GEOM/images/extract_result.png create mode 100644 doc/salome/gui/GEOM/input/extract_and_rebuild.doc create mode 100644 doc/salome/gui/GEOM/static/ExtractAndRebuild.pdf create mode 100644 resources/extract.png create mode 100644 src/GEOMAlgo/GEOMAlgo_Extractor.cxx create mode 100644 src/GEOMAlgo/GEOMAlgo_Extractor.hxx create mode 100644 src/GEOMImpl/GEOMImpl_IExtract.hxx create mode 100644 src/OperationGUI/OperationGUI_ExtractionDlg.cxx create mode 100644 src/OperationGUI/OperationGUI_ExtractionDlg.h diff --git a/doc/salome/gui/GEOM/CMakeLists.txt b/doc/salome/gui/GEOM/CMakeLists.txt index f7877081b..b765fe7ae 100644 --- a/doc/salome/gui/GEOM/CMakeLists.txt +++ b/doc/salome/gui/GEOM/CMakeLists.txt @@ -66,6 +66,7 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/GEOM DESTINATION ${SALOME_INSTALL_ INSTALL(FILES images/head.png DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM) INSTALL(FILES images/head.png DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM/geompy_doc) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/static/SALOME_BOA_PA.pdf DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/static/ExtractAndRebuild.pdf DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM) INSTALL(FILES input/geompy_migration.doc input/tui_auto_completion_documentation.doc input/tui_execution_distribution.doc DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM/input) FILE(GLOB tag_files ${CMAKE_CURRENT_BINARY_DIR}/*.tag) diff --git a/doc/salome/gui/GEOM/images/extract_init.png b/doc/salome/gui/GEOM/images/extract_init.png new file mode 100644 index 0000000000000000000000000000000000000000..d60855104f9c49242f709ecef0f5088cb5052bda GIT binary patch literal 4948 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/images/extract_rebuild.png b/doc/salome/gui/GEOM/images/extract_rebuild.png new file mode 100644 index 0000000000000000000000000000000000000000..f553d263d11d45ca266c211fdbb02b221215d760 GIT binary patch literal 39127 zcmbrm1yodD+c!K0AWBFhsie}~q0%i#cMjd%DoBTbbSWVsT|;*>bVzqech|Sa`+eT$ zzn=Sk*0* z1Ag6eRFZfLDeNcN0B?{DWh6u)cZfgV>T_bi7F0V)4MzwBqYd$MFP0vI7;Hpwl9Cfc znSVm`h>RyTL0JlHdgdgi?j&MsZEa%X1QBsCF>o?5e(q}SWcFM_O75N7M+^c8FOVJ$XNe*;r&B4v`4#j?-OkyZ{$ZBnebp?fSgI=A zdpb=4=x@e#@c6$;J$*zNeE-w;?4cL+{nxi$P~%}ge~P_z_qFaB&jG>pIezx)y%bMq zhu!WqFEWOAM@UdmkR+b>;o@7r@9kfLK@VO3K- z#-X5~$Y6OvL7~LiAzV_pN>rFrb6SRN&=Q?qv>w}q{?i;sSe5z7y@g%Rw|Nx>MZ)MP z`rB=fd?FRrDO(n?GkY7JC4WD{dJ6Qnm|yt^Q1C;dtXcY~v@RWmOq` zK2KRBF$0#zD2uB-LvPM_=G*MK=iT&q^vUtgNHYJP znH;*>1Io_2pis*KI+#VfVR!Ay9siy7fslmnJZhB@MYW9bt)z~I=TjK^p zGxo+N>rVw(w-x+@uS@l`@wp#3LWhT^=&a#(1d ztf$yXeciUs<=IY~9QTF8vHD}jwVTlSWt_))1M(39?AAQ9wKMWP!R%I-=e3~&WvjQ$ zFZnw3e2*xJ=k5slk~tR_8Vbs*3&OQ>OS|otm>A1SOiHr!zGjh5^SS&NMU7l#qn+75!){L3jkumMxs$IV z?PpkLRi<72hBYPsr+2;%q(#KWK9;5SK^(V(kWb9^1liJ!bBhj3U< zeF+ka`KeWj-?%HRy?vrs&0@foOuw7>XLOSgic`h+F*!6?d`^D!*Ro%{t5*MyBuRPs zwa)a2qoeOnMme&Fe>Ct5(_W5@^81lvjt(BF6b60yLi?(?#?Zy?zJB-ciPvrW*|lCE z^muC|bA{ z4u=kQM=HJ3Uu?X)31c^vAIg-#JiWO_Vw^husXQ%4H=-NGnz^?;GSJYj-<9cJ_CtX6 zl&m8xJuuXgQ9P3H?OvLz!{za_hRZ`oGIz5kvGvKr`3kL)rSW1sL66f{+j7A-iQBzT zaB)`-76x_wWj(&e&?+4Lp57a*Iq5?q8N_qt#u-V|`q+KkNgSG!p4bt`I9*+9YU*)T z7bDVm)3UYI*lu>68NV1mG04Ho^=t{|&9MxXY;`>zpJ}k36`NL@lWP2c8l$(AeSu>>4x^@zmtW3ZkHaoA6?QGR zZO?Fzv2%8Yj_-O499@?hUTL?pM5Q`^?|q9(>uB#%zOdyJG3~`}KA!c0OvsvLd{11} z1^L1}umpM=z`4wji!9-z;J>}iA)oHZRH+*U-&hPJFHKGpFvp(rVbnMuZZvb%qEGX5 zAwu^1$lP$9_t@GY{97CoS|k#d%VB@D1wAvEVU+lJFT`1+6V21%h(sKhHEi0 zmzFUVZ!8b+IN325Xmb5<*_k3a-*MH1)g?0N@Hw0>EOS`R#08T7QE@x;x-^et()#Gh z$V`%o9~Bex#^v{C=?a}JwjDh8)5&#>ic8MjYSX95Tn%!yuuA)tGxF-($<*Ub4W5qY z98PrPRugS$={_bGrR{h8BbspUzTKIUS(m$}k0Ju66Lu*nmeHxs9|HsMcenae`MY|% z^yeEyW-fg1B+hJ7y9Rth1Txpj4VH3EC-xU5!iY|I;PH&mL2qw&`#HnSs~Imvhmz=+ zRC#%qnpuI`oh!Y>r4e7~-$i(yeyQu6crf!4+OMJ7@3SEbIr9p{091UmVSz@e5#8f=JZ?CA!Z=?<()|ia}q>;?4)ZSFVh`Z}EE#$droY1ir ziM!i?i%`{=_;@|}iC4*)F){`TEQE3<_?H`1-1_ZSKU+`zx@WLGlU%G%2aAJaadMcS zKD%LWY+H9^YDBu|@JLbMGT`8gcJ23XHv79!`FE>gCMME%)-E`#L@Ye;$?w+rKau-Z z?PrnV2Y{j4bi0h#RH(m{vv;wtOg?MHjB>ju|CXkPGhIiJh7R5Trc3?X)zOiX@&*k# z6Ls(M1QHY$)-qj$=PXG4U}1G+ifbYl^q=9hovcPj+PMZsd#4j7ukZYP(W!|c&1M<8 zvr`ZfKBq_N$OTe;#lAc7XN?Q>XLC8?=xV$5XSzw;wr@L|7%-zGb_bUP@A+ z`R458n_AKH($cc?{mdfwoAAgI_5AE|tqaGhXH8~5tCBlD(Z6~o$9tkh#@abtRWJng zk>PNpDHGz2`=Ktk*786Fa%~%yRO+uS)u-jmXwP}2J5566oJX>5{q9e%{!pA^nx(#3MKN z-`_RLpeb^4-%1+OZyHk_ZVCJYCG3vRpW!psHFaS{mYNM|dz^X@W`3ukl}~FQ?~I9} zlqmDL;fFaBaay#M7A8=XSKS!O8`EAAPcfg z{$^J+m{u_x@R>qGejm)H=S|u-A28dxR2+YPT5INUwyEnPNIe(!Z2#D%pP$@nxfum{ zS*KCR^{gtD97eu=gUQWqvSgI6UJ~}kk38dBljPCb?K$^h_K{Ajos(0AO4*<6&sLL{ zl-?c$u$x;HVitZL1D2!--vyR?)=4FHi}wwEF2e)K3E%DdI2;I%+{xYLdVeJrlFfHp z^^+EmxaC>Cd5S0Vv0XZqZx;`SxN?~7yq0+6+r?93W2nj|uZ3RWQW`1>3VWsm`qHTj zx1$hexV4t+NP(7TjY~c0I1y96_YKaWjP}}3ivj-<3#l7ehk3cV@#+YMj5 z9Uv2gxUEeR>{~j8-oS^<$~{wi(`uu06@*%>D`!J8GjWax0&uXn#tW|l!u1?Zov>TU zYT|VTYu~+l*HqLXq43Z>Yq-2y6` zt_l^TzGZwCt}Q9IK8q=|OimeixUz!kb=sa;cXhjdH$DFGc+Zmn2?^=?_6kea-Gmdx zceaPIa{fpnLH!(ixf5l1bEz!=oj6hOO3Y&1`ooZ!vEsRATI!{%P5lYJwzjr9Y>6|? z*G0Pe%Dwtb(Po=vs8&tFC*-E!@d;tjTtlVwYIwHGG;!WFNr5&mWg(|FA-RA*RE{`0 zF}9VSUU+5jyHVS%*BAR{k&VFyyowpiVuurPHuf^+4Kt#e8NuHc+(Ee{G?}q+LK|q; zjqgXD<*2uBl>67*Vr;E~+7~j`e`w=*x>(UU`_$eM_Xe-bOY)HgCf5@5X}Zt|3&-Dh zHd26JYXvn*nb5^=x$HR+(N12>7Z=qqXXe6Mlh*^-^EqFlTmp;&U1MTmK8A+!pKNlk zPAn4Eo;=wSYRScEj7g0RXx49PufS*2bZs{B%qg4t%4Y9RVT|+wU^fprKFnqP3 z?uACsPrJCV@K&&hhKg)n%Vs*8G!T##DXFQ*nD^+Kvs1)=%}pCI2Pr~W3N9{u$bR=| z*OS~vPur)9Vs!-3uWgr)gXg>Z`m*8znZuLHE4`B_>5l{?mW{glrCTT4!}*+vqum4w zXKomTyk8*-c&wUt`kH$6l6i+<$GY*PIa}0hi-6CP)nN%22K$}a*tara|B(gclBXw z+vpdA&-E@vKD`%DsQEE1#$AkN65gz=tYI~*)YAo`N=U@FutcTDXRgNv1-+EjUS%oq zGMCIAPh)wNflYg}d1sAL=J(zp;pNLgOz*#6F@}K?f0w0qW6)yErZ)wV1=N$6TUHx> zqMhrpgXhDcoL-BMg{Anky3He&LR3_AMS*pD(sklj>vKRy<9pB+78e2Fe&B4mp(Z3I zDw<_z%4GZ{F1GXHXnm)#hK-k6LqY-^Mz`WNWc$Lr*B|iR>sSBHWhwsW%YSYdM|X5q zB_qQxr1Zl3ERR0+<|$Ux7PqW_;Ah9Xg)3+OqKy4wJEX^0Sh+3%f>#(?p+3o!-1H}< zsciv*Y+)EX{9kLl)OrgY#`gvrL_V9`<_}N(>~|?@6N+7%b)8fB20jknKh$1-Jik_@ z{l;+RXB2FsN^glNm(0|3-9q?j`*hW)b$#4vZdFvK_^-gXqN2Z4D$tso?CqP|+uL`2 z4z%_s^j&sm%#&|m>6ITkedEuPJJuhWGVl%d9iGOm8kMydG!L z>F({N0w-Wwe}O++L)%{%Qc34Rm;Rqk87M| zP9HFYg+(lj+uK&21iDU*=hhv)&lnOKA!XfRlUC5%>x(*`GcoKK?0b^3(p0Rkh6)RH z_+1Ys*VCiEBz!0 zcInyirJb=Nz4SMJ$R!4?$XbaB34~L#a~Q(H!jO!NjPt`h=8LsyTONm%M@99QNd?=} zw)K4xr2GI4BWF}f7*%L$z^pV9JEtZm6Tb{T{X22+o55S zm!q2b4VkR~+9vC3P-9)6!6xSA?KN5Ah=NYU@v>~Eyqu%PbxXc?mkCD$@??bmji{(}Y)Z6t_Tk#5S(`;goJV7onx1zot5GMo8|@*h z^g-&_iW549EMKeV+K>GF{7@6ITQ=3ymeH7iSE4^B>~g@hVL(}GK4st9B?QA|@(!*4H~P zU4M@h8?;JSc$Wn2KYE)Jpn4Gu${2S*9CxMh-Nzdh%^b}RS;V58%O;p*_L;6Rp{JEk zS!lT0T?UMDZ9UzW2HZrjIxNNu<+Qa^bS{QBdwRRty1P*`ha|7}4*UcBr(%f(j9CT* z&qz>w`MZK~XcL6IYpgZItkDQrK5Psqtan9GlJGkCgO{dYm{x5R+^@7WJqt7|TZ}na zedoN8F-XkR2EquScE??c5oEkQ;N=9P?@E-!BXm@1CZ-55{|t?cp0Pt^6RinmLq36` z+O?|8sHYhl8*5TKUoJI*4PW*NrZkj#h(ja)oSU2ALr$7c2x9Cn$Hu~LJIw+xo=IzJ zCe3zoG8Yo)pQcPQXqSIM#i3c)*ys+5qMWF6FDsZaiWC&Lu%N>fJbtR7q46;C35+rC zXSiaf1X$C}O`a(C2P^n&j*L;2L zb$PPa2`<|jPVTmU@9@bXDjBh?p&`X>_)Q{@y2^Z0b8?POr)|re zCWo>8xbxT&$^^)*FD3teqDqDK+RMkdHTw)89ha#p2ekR68(6?U7g1>@V5H0KQW&>+lBljJk_!HIZ1PxO@L7BOnl06QzBkGub@5%aqE2o528!w7}%p@=k zhjQITx6K&^R%c34+|(k!o6k!lGY80Fi&IuqLTm)|1W4_31GdDft-@NCe?qA@>*(QM0mXzNGKvNN50TLZq@KArk6A&4ht5H#g_z;W332y4QG@_QEgl zYpPo>bjG44D&Ce_aQc&oE)nTtjNw9?d$%VR@A60GQHKYzzof^= z_YoC(d_^?OaTdioiI(Z_>JA{C{Qs78%{`w6k`S|9esJQr)PJdT_KNA)eXmvd|9Dx9L51~Ot?x{O=aq>Rh8BP$H z#K=nH6Y1C((eCPBSMIiTDQ^ypXVsy4J*c`i~6O5`35@Lsic4Btn#{h zLk;mGw8vQr=|T{%yPGp=52_Cip41^TziXZ?lQZbI#+O|0Ytaxm9A30nqbBM?iHbwL zfACRhSSWpo33f&Q<0SK*jA#^xxv1t}Be%|CZ?FDmI9n$7h`!Z~1ADLriBl(a|C}$* z8b#iLu9l{gbTe8#N3eQ5a`~NI1Tq;ivNPs4)Adsht5JyG8zUM3Z40kh>|ZT@=KzWZ zjhxL=$<>V6xe-aSE6w4wxv2yD2#eOR`RbnZolWIXnWe?|u0;4z3*oXcX*ONfTN z>FLR~uzQ!Ok(qgIYROQ0mThl39dNvL;9G7rgr=tEtq8z;P>U#%#pusBS1twS^Mw^; zV&JCcNsiwGCm?D73a2P8;#~gu^4~W6-R&QHtPr_KHTDf1uEp^=fYWg>H=y99PP{=m z-Rc6=;L$fY3E2AAar!4H{|neDRG@|ZJ*}-R&i>4bpw*K;1Q4X8Rn$$L=M1yq?$@^R zx_s)zi^IUJ%a5p-Pt*`l8_)`X+}XFI44lm7o4JZq3p8gO;EewM0fRpkGcD#>O-)T9 zeC2yhg$X+2vkwqEKE?&7WfTw$V7_<+k$G~&6*b0(qxFHKQ!QI|&r>Uam3`Y=L=UdU zV*o;@dk6X;XOSkdeoa-?!qSqV>wITt;DJKedeiNLDzNE40N=cV>oh@6xBX@mb6-!- z%j4Zv+H@~NEqnmrT^h^X#deU(Q6bO2$-U0q(yrT;NEXUa*b^#mtQU+Fyd><5B(G#t zkdiX6_@m6{x+&Yq&yS6b{no_=HhXC~o=^RfC8)M$Ud-5-s;KdnFO}c<$M|ghM6GL4 zftA>m&NbI<@Bxu0xX0YO33lM16J*@kf&PAIUlM1z)fhIo9dkZg)-Kx<%>kI)PwNGV z^2T~fP2g6mA|fL0huyT3zWT!C-q%>3zH?d@_1S&&HR%aoAH4?MGFU2@`ge7e7x-pk zZfmODcpi__?QR5&h*L;mi2@b_P8olIPOZ!0`j&*KoB!;kX@8nQXFsXHP49@TyTfBs z`E-M;$Z6D6qMlC|PpnMnr}l2s5DakhU&OCkBiFa4CA4< zZjVsWiMg^Y;|udWy-DSgxsVn{bKlR5+>yC#&)ma}a3&P?5%9h`X&)bNAk!n)i;j-z zNm2WKQ+j@Re)#V&+2Z2A@%Hp(+d_w`l8=9x9ZarijDf=LVL+c5(^R+L4|KjClH-rnB8As+mh-2jBobvGTKG?&HXWM4c|A`VP%z1ir$)_9U|O{<)=NuE+px^@f^!%A^!UW6 z;FuU3@yw|6`DIjeR7O`}cyb}QGc|Y!bQNVOSK&1vs;a7*dvzCCy6Wu_tVnS!U%ak^(Ax1*QT4u z3GXjFSlx9s|6QPy^BmafGYDIB!v^xFk#?2 zY;-Ds;{z~o_+9|le}*uO@8SPmU;n2p@~<+igjI%d4%rs;7B>0eWv`bdH@ zWQfJ;pF+zLe-~)QYjUx&mdw;#UtiNP9GS-c?ufOhEbRou50{21S+m08pu17nV8Q!A z(JZAwmR+5HcTl%gi!sx7FbEX9#K6Ev=v$*hZ*g*R$Ul{1n(N3N$@x{^m%$~l<*pm$ zjf;i#85IKUO=$*Xd1Jhh92`I$*V)-wrhj{%f|Byp%a`9A*ZUbTv}9BHoUQ5!6$Ec^ z^Hd940MC!t^$31|f>G?SDy^-fqtRf<3+D5~Cc~0qrwye!?{yue_wP5Ri)`W_ z@slq}Nsm9&*785WXVAYmT&1F>wqI;P!XV{q+ny|&gjo|`TwFNq&823`#4Ai=8<-I3%zdAro`sN6eA389#Dd>uv7t?pAf_ zj;03VXSX@}%BFf1KaNpL6>2MMoJt+eA(W$jAhx2#W@dwMDM}w`H2g?!U7kj?9@chKG ziR*SKMAvhN6R0W(@x)^6SNrjLPT6^Odv6M7*>yy4D6&qHEREJ5AYB3On=6{24lbxQ z5Yu$MKNTRFG~Ziy(3=&2k!t7QKtW5JBTB5Os0h&H((>|yrv1fM;K8hibI$>88lT8+ zdbkwITndH=633wN*2#%O&-(w0WMI&)`hplo?<*IGcmzo|oVl?# z>>0b2N#oTnf5XKZG0>4Z!A4n0$w%|vXF98`{xJxq_Q7DFp;Z+$j2Uf`u0H7kJ0x;j z^62-`^s}#rCW7AQ$lEL2d7fV;7umbIGQ0MQ0=WSpwn1IP3L^B*ZbAYBQL3w}IZkb@ zxMwrmpG1%d-bbiw8fTY$NnF;C^(|dN*EF#)a#H3%C*o>qpF~3GY)N|rdUx%?J%TdL z0tj$!jmoX3@qs?z;K0UQf2_3lhLh0B#0q6fe*tjf^Q)`)YSP@?+;a1g0HEeQ7_4)5 z6uSIFdH?=>X(2n4az&0J^N}Cd>%w;>Cmf(SvziS)2b0T~J~<^Ntg@0Dl9-q{nx_`o z+uPeCXfJIJmU*Gvn>TM_Z_|SRkFJ3i=jdcl%Sayyu#;Z3f+L_lhkr674+rA!x}UJ? z7Hi=X6T|DOj{r7dCScNrygb-Im}FWCZw@wQX0)}c{rw*T#mk0&LyI9!_=FT|eIUJa za`KskL?^ZpO#lXIPuYNwjJSBf&Y`$FFyD;1>n+Eb(tIw>Pq!yq0qK+8c76NyJ^(hg zSv&I5(iu`QG_VZ-bYclvG;paPU}<*u^bFI>0|8(=#0O_2p~MI=2?3hgUWeq*5|t(5qO?220jz=;t9kc1=d44SQQgHuAtvq3!>tUsbolWjmMv#yGSxc4*)X}v(VIu0WM9GhPjGUI!9 zL&EFTW~1vS%5${V4`Lx}h`!g71nIKTQ7r zBs@j$zrPo8ehPZ|=3iz4;7en~zB8QwgZ4*2#OT_KP3H~rK;f`q!dQW3>%wq`iX{Su zzI&s%v~Sl?@Hu~8IkMHgE>R#d_%qOM@C&CoARj((-OG;4vm$==>Xj^dsx%;K8*Zi&Z{NNJG#{pQH|sjTx|`r7(BUDFx0K{19Zx+v98zgaKY1C4~DL)^#)h^b(7S(+|GSb&y~_GAzt^`A2x$ z4YmY0Ch?#Jt#%c33$Kf@c(0=!ZiH4kuIpVeS`#uLBP;#zIqR#awyZYnRl4bpHdLHv zf*u^KwMG*amIOWxKBE2-69tWy>r6sd*X-EXICS;>iDjk}K)P2DKH_+vmeP_qVmfiV z>;lB!QUD*cCM)MXk^v?tUTj4dwTZ0uA#e@7x;&5mnqpjg_iyyYR;$5e3tzL`>|WEy2PlNR zhE$3}iqxBQN_DqO@KB(qE&>8Q;e$~)NI_0W=eSUDfGftqV zH!tI1B__JkahlU1d+v6n?a(Ur=Kf=5UxdWXcy@MHIcqyp#R~96y!SfXlJY;1n}LA= zn;Nz)H#aw2GB;4~M?gP>Is6aBpP}*SC)*b8{F-x7k&#pzc1vsP!OxxMQ04~7NHRe> z0T-}jfDQmmEZHIotfS~j&79C2Y*k)f-WUp< z>M%?Za38ku_G^A;anl|@h#uS^)z!CXWL@I#amh-rxs=C#QFjs3W60jnz+EJ$o?T-%~L zE;e>H;5@VdIqA+*01zs?T@jV>SGJc?5@atpsJ>QJ@qi%@3J*8wO<-N!H4@wU3hOiK zjG(r$CE3{6SXo;&WFhPkv;oEo48cnrG(2eNqGMxK7H@{vX8(hxp3}&Zs=;nr0sz$J z?*cdg$rqPfMb>bMJ0lK}Ks0IqGJ&hvGXp!EN)R;VdP2Zx+~SW4FaVq3$|Ek@Iqh8` z?H;~=5uz1>6&wMsgtj)(YvL<*`=vIp5;B~nEsM0qZNkvWWE_;(vg}B82 zi#nP7I)uoQ+on6zR);ne|N2$fM!+`vNYBc-dLuMXRMdtcw!T-fKu=SJLvl~4LAv(* zL+_>?_0)OZx!H)sU-kXFMRl(t?n~ek65SrjmO!pPJy-e#cF&koohv>Lr{>im~+IPQo@(5 zPwj^D>?Q6;YZm4?w(||tQ*;XT9w&fhK>#wYy&|~710uy+5s^IS>-ZLbZ2~4BYg^ak zL)fe)SlCJ#>h`ad`JDa$ckY*i)+!tBT*xO;bMCLSqASeu;H)B96s;go6BJ{Z^?2OT zMuq!LAEup?LzYUODi05ja&Cb`nSb+#X0s+U7BG!ih{8{g!jRFVae$C#Z?u1MK>dnW z3T25%#R~#;f53Khc!G%vhn1cat$Uz}{=Wc0US^ zjLZR0PeAy_eHVCW^kiJPnoK388PV~)V8OS5(RNtV#*nk!ZCa3kE^W?z31h%9?N4^| z9U({&^bEMYxmw=X(8z_+jj=1@lF5qCY1~CvSNr)r095`VGSbrGq9S7_6qw5syOF@v z64Ve~DVk(I0P5h;ek^FZy8$ zeN)*|9h+;=4q#CXhLfORkSu&ASaY~5&OJ7p`#5^+)t>{6`I6F8UDj>9ZoI5p#CbPa z=a;o&{6p5gbX0~+91@*T1U(JM5(A1$^&$$2fP#AC2R+uzR2@xZKSI~KnC<*iPH zk#ggI7^7D+a(QQ(8FVeyDypyloZR=CRU`oI-ojQ<;|~ya6BQGi>}mU7c&&6@=Gn=C z$zsN520d5`U@lmo5G@tAmxFdSdK%B9BMo#|kCR=b*G0PZk5JJU(`D|uf2rhc-|q*1 zcMS}z1J-K#ds_n*)7QSE#eg5jq|;NoS0@83J|M=K0Imh_?foz5=>yS0)LuXl&C1R` zSouneihBeLx%Cn7Uqd?tl`_}tQca4Scai;{BNwNVgHL^7C7yE`pYh89GNXv-J zx~;Y@f+9lJ7MlGa9JX^QP2XP2(%__DU*Sx_EM+pq!y%Hgvc>=&07LPc1G5=|+=08; z2FyxARXy7%d` z2#knP(7pf}n~c3!OSZK-OHEC62k;+&63;|uChhX4%*@P?j&R~mAo{@>JeS%~0h=-9 z2Gh(Vg~z_dW)8IZAOsNwT7|(%P*iq6@QH1a>Fm~))gGBCkZk}$Dft|HHt(AbNd0h? zy%7Ycas{TEoM*DeS*Gva=~GeS91iz8>hHOx2xIvL3pkXL{#;Cu^XowWsn;kJ5fPEl z2L+i?)zAuQKYsWVT(R%>i=X@gGLXRWzDPpv=X(6Bv%U4(=Ck+kOneB4y)Vp@-zE3! z@Gb8w%X#lzw%wA10^bUR7-~*7RXwyqrk-M5z(1pY7|Iks0yhm*O1IN$QyGRx(3OFI zy**nS|Ac^PVs17z`=ulVwDvElsXEZf%abj~%VTpdZ*S`(`E((0NG{ znS_;<6{Rg1Ny%a)(!W87l2lPhbWC*h#*gIV?V1!p96Yq9e3d->xKFb3>AZns77H!a z%cJ>=q86G=HigwrTT|$?w6p;7na$PlHZ(NA;7aj_r1*Hx?%LdX*IMGo2TFv?OyKxr z9)G^KEW|{;DbTF2G7%II0NQM&T&3C2Cxn@KUFQ{mMw)@5CtB#nz&bN`>oWDQ{5xn=z&v|;rn#HYOT(ZlQ|)}WQEtQKxMf`# z9i3vBtd=Q`uBDF**pL9H=efwPXapL!r>6 zwY7k}JbD00Ws~`KN-Oxy52--*tG{8>uh&cDrEjsyV3_OM)G_fr5qPhqATu>#wg+2@M{oFX&!6Gdw@Jm9dWpM zTLyH$Nnrk1KWBXnS7p4|o!$edM+wl`Uc*g4m)rUI!Ll*b82jnd*V8a-Ui+noIST2& zabAlSnveGm?(GNJLHknLCs>UR4i61ys_eZkH*(^$ce$*mo|2LE1NDZ->zsvq)(Hpb z7eGtuXgJG~Apm(_IUr8}Qeil}B9;A{+v50Tm^fvoMEKf7i4lkO)K{QCZbs_H9V~bC z_89Nq_<`V?e;!+O3BHMz3!zumHo<%K3J?MGBrEpKQWs=xUyDAawQm& zpU;q@lai}Z_QP7%56`l?9wRUe%IY%(*LsYJhM!-KS0|AzX&{I+wnf6h%`(Sqky z=PfBO)ledDjD$2ZdQKBTD*VH=SLG=wUZ0%YEur6G+c~ZJK~IPhd~I#*@K9LI?y!!Z zCNRl3{Vq7?hkVm?XRT5rT(NGKwnJEPEpi!1>C4Moev?*Ab&0(Rq`fc&2i#dFa~aV> z7{~-DUj{a4&do#vM^sH6s7 z$bw7@I7->&?S%S1GB;jE07XX;@pTeb}pn!%fQq2w6VKk6I*%#*S#b+1p&eo`HNo?cMtX%3t z{7P6j5UxalnI=$LZbKd)7Dd|LsQ}E~(tZ!{Ekj^tB+62M`V7nwDIcGPmbTS}tz{V{ zhha{&cx?@2G$3WfCN$d43uzUlui3g?7{`T5^ zs=~7KoVH^mPpydfRw~2py}P*4B1)vo-duRMaZ7Xay}!vB*o_MKq(*HJscke}idEA! z0OT7lu6DPzElVoKZ1xwYp7#x2g~b>J4NZWWY8|*^DmzIp(eP*}Y06Mzs##ux-WEYF z+~0!qBseUL3doa%I+M?+gmDVN5B(e;U)MXmHBZCH z8SZm)1w!|4fr9GXE4K10&#YI}L);^~N9WAIaJ*k9U!yDl2(pl;goKj%`uf#-{h?@HohS0;*P9(uV+~0%6d^CbZqqU}HGD4#-?tKYk2@La^4CthO24 z4Z!3sD0x?Za7Tl!=WWX>;^X5xcXn*nYZ>S5w-_sRVXz{28miyW>9{e60av0u3;)8x zLKCQb8dY{LEPv;}0Ck$zagD|I)(fbu$W6n(OeUR?{O89b3b{J9fZ#HqG20mr&HOj!NdX2tk44kXMsHP?#*&C zk)9H%R;BeSyr|)!{^3eDgHFxY!NEZ#xO@svRQ1u?aGn}7&|bhK_t#07_|I?>A^;p1 z#QijZ$44b6!!yJ}6NG(*3=9lnr{czSJ;Ol(fcht{sHBsD*PZZCfVW@Qn%$9{#OyMj@fwbl}R@6=`mS^MvTChj3=lBC^(J|0;Exp5sNz z1O7#k%vvy;lAAJNy9EfPL>Ltv->=bAM3@6KHH5zg;0*QV&8t(|y1F_@S5Hp{5N_JY zBbX}+|F5~9AZ;!4-`0x7^qJ@7d}~B1zjQ(4c>_6U!{0>$u<=O2TzxPgaDxUw?hN;z z2Ke0R2^Ak*5-6EK8gVTKi<^X$)ZWFVV`vCVLP7%6X^_9<6TUgd0p8SuCS$hA=$g>b zC*V!%14XVrI$B&N@^Wzr?F4#|7S5E#&=CoAJ=$%+7$=9u@ zX}cB)#F&&52CmNkVz8*)jhlOVc$C@=y>;1}?8A%_URd2QsnyldxV^oFU4;{K(|~yG zuD`a^19e~{`J6AJc+Ad*g6VXyQ#n61rh-cqBF~0Ue>Ns2)XBUS-T;{Q8Qfv+%Bn=* z2>|>Gd=Z3Xh)&Fr^-=GEP3;L+baeEu@^nBsmPhV=SS>{Be#6$JZX6BAn|uY;h1s%o5d z&3Sk2AJVJ#GjA_1s}V4vVZ=?0l`}0<&X&Pf)De?qrZ{ZWS;N!Z|At02m)ex(VE@V6 znVfx_?RELwO`GNJa=bBU5)TXn>GqtQUO((knvIRk&eavsI1zvi_@5Ju?YM>t3qE|nRMS{@#J;Ci!6ac}#&x-yJBW&SG* z@EmYHAf!p>J5n=!RQ60bzcTWr<>N~NkH__=3BrZ%E);6F<`9L1UagRdojnGKdIzKL z6=HuHt%W55%=slcx~2CS`!fMIyUCCGGdw<5JKS2>?1c1p_RS!v4J1wQ3@kOUe9YhH zsF-U7V3PNP{>1CH|J>c(eS5kRz~}|G>Ad$j7yzu6C%azlR2p$5YZU9>6A8e`g@M}u z=x95z;zE;?iCt%%2>`(@(-N|t;sDvbKfeoz!IaKc%oK;20K>_6q3I(UnE)X$qi#M9{WDQQ z36EngW7InyruZS3+EJPf-#QF_iD1OeGmZn3HTl0XceaMw1vOnF-RB$7NO%UhAZ0J9a6w_z2g*ioGIx=2 z5*HCj8)xXagZPP<2Khx;aPW5k_a7o5Vd3G4$;$Ss+_;%lU^ZRTS1akUod7QEusy;0 zLm}O#eYyc3550+j$W8<3WcccRtDUsyYxMMFaUaZL#>56qyu7!Sj3X5~>0~+R2cED3RY5JW@Ev2Og(+ zj5FTuLMN;I##s;gvdHHqAP{6n);%tM)*zhhE>3Ad9E$iMfGV7xf*c7OFdw1)RYE@4 zZ-6Z5{?{1$%s_EBFgM#d=62@`@pTRq#jc@VrHM}N^A2|?W95QcKXQzpq}mXNidRcL zlkRD8;BTF==A7<&I`x%-yE<>?>kqzQMM+-g{)?N%^-CA0&6EtMLk}Uc@mAh-N1gP6 zb+5t!=aW<3acA$JOp5W2c(~$)nTx<&P<^WknATsA8jeMyy6YV zETE|PZsvpCuklvdxy*DxoHkjW$Km)<5{LOG@YYc0oUiU|&eMwI7jA^?7tQy$1@UAR zFH@OfrAwfFMBvdo6fRQhh1J#1;33d1YXU5+k7To+O*6gP+14SUp$C1}wu9Y2aB7@) z0zeWnpas6H1Zi z36EYfMX@mlgp>yq6Yzkr@)QjN2O9T?4aJ%pS_Y=XvRm)L z0N+n}VZqk&wzcP`5O1t=e4HSZfKlAuo>f{}y4Y>VkU^s~Yo-)0RpD!enwuLB=zfUn zqDqna@KQ^8@hne{qn|bhj)sOdsIG>x)DkGo&BDq0`K3f#<`>HBZ`7=a`W=HZo zMZZtB&u(c2^*a+tb|mnb&@C-3D_=6a7Va{G@a?aj{l)vR=&_~*^I&TBz{s-QdfOU=;wwfa7L}63sDWv z$?0h$aMGX>XG+f()i`YrV!g_JB|V;(lNTxRxxEVxU*^Qg@}a~~iA_ulz8CQT0%1!; zQ_96nN;>p&1SC0jN}LM&JDB<{p7iv2kGG1Qr&ay)G2Q^94K0ZXC}!k9I=~)IPcOgs z8a%!%CMMQ$m6b*Hkl{%ah%*7P7!xu$JRA*gbkbp9WPE`gtbEJVvnlSZ0OCgbJ0Z3Q z;KzP%PSD?%AOZw^dgPe0`@PvfAgK31qvpCNjZz304-b)%mq4)b-26;I8t!}Gm62aB zI!Tee{$(me*zsLz7KmZ&H${X-w(j&!1C;_XpotoZcs4m!#P8p~H#RnYv}Ze8qhe5B zd|Y~mLAawj;~7c!ov<0wMiXz?(XXP07j>0 ze$`}Ce6t8RHVMn@C{j{V7L&Aiq(?L~G!CmdIXUoHy-7z<;2t(yAIbpB?!n^XB3@j< zA4iiN6R1tV@v&2EBe@@Hh6U8jEC__U;ND#BhsNjU=Lh4q`vh-ULMhp&r-; z$Yhmt*L@U3)k2Q& z{P#6Xq1X5z2`06=cgW^UdBS17L%XM!9#vc(CnT3Q< zDk@4!#)t?dG88g~h>$V!5T!ygH<>bzQO3+^kWvaEGGt7q%;R_7t-bfV_Ph7{KmNye zeCt?i9ZwHE!+l@ZZ#akF^$GOV^U?5IAqz092NM>w8R6z7jWsvv6uTjJ zscGcf|5-miJw3>B|K|x{jfrSB=7F*aG$^(m=6cLE@q4DWii|uVDaoHbM`S{0)UbbG zZuR5bf%j%x4~mF=8<)-tb7awosmV!WzB45mP8WHl_dnjJ zDo{{Rl=)>5Ro}~7EP{9M-X%c-PQ!kXLQp%)=jqb}9N|MO)SEVCG&yhGYL>cr@X`kV zAZ3oDS9j>eMqIVCt7@!V)*lXkkea#+6!wOF`yjf%PKX4=oJZL>B8GORA7o6h@~Q6j zt$wKzuC&A2EMp5O!K>rt<>gOJ>NXvw`6Q^Jo;Q&%6kzyudp!vgCn*lyu74Qp$C8kkW*8m zBiW(6YIr2U3jKlb;lrWFQZ zJQ51B?Dc6RRFi7I^$3o~A#w(e|DJO24TXB$<2C-v7cX81wf0o@rq%F)#fPf=$2BzW zO&B2Zk&%(*J%7$34QQ4F`{YxhjUMTklG4q)h4y_X(4SY=*DJHhVmF4`Wo8x@9?mZ) zK+{i+f2`Y|1xd*MQsjTaxL-eFztD01a2^>MZuFgY_VzvMr>1X_`?5wiJzo2!{;84c zV65sDG9U2o#H9@k3ox~VNl6U35`zTefQ|aW<08>kbY5Kp6O9{lp&IPgXWKg13GP{jZpES z-uQ}!h^VLl2_3rJqN-%uoWXMCTd^<3%tW`f)YPo|^yyRHvuBzyEqZLzKjmFY+DH-F`jrwxm@79P$}^~^A7dU6uOmxxS$<$Fc&dg?7kFg!|T z1bsOsD@!&#Gn0^-dgIO=8V|4zSBKB0sQN-h3vI+icQrY@vKuXNjfm#`UU)dqmfQBj zO*_RTB&dh`UIo`SXX>cy>o1SeJ>ut1e=^I*l(CusnlGTTQU=z@u;}O;Mc=(RpxJXB zFP{^5q+_G;*~yEgKlc9piu~Ob;+1PR8Th(KNAJLq&BnoD3MS(#io8%OUeUa3zs+6U z-Axhcg+)aJLPP1iRu{aBZZu+{Vku$8tXq_%uS=GS&3Ef6sVPPQrvv*fN zDRLuDZzOKf)2G#h|G3*$S-1za6$b~$Hfaww2q>yS+2vj76sOsG=w|iH%e!+6`;*>4 zxN!hdcCI@4<{w&;Gx;y#PND@2LFA2IkeGNF5<&|}C_O#>8FRf;r%n}@mA%V0ybnR& zH>LGjmAVdO=5SO>N=g}hZJ^g}*BxpuV+Bnj;Nsgw*WrCEPTKP$)+_|@>vY0%Hw_0U z1Wf$?U8`qX9)OOO8f#$pUV-cK0V zU%vHtOV0z_3R%3$BycZdG`5lLYx0_9Xx{c*xM{UN=FH@g-&n1tbwz@AqoTCOY)5vf zJ$$KF=3Ud~V9_%)bQ1#!sE3UcjA4$e^ZicSU1dvk7XsSn#+P}*l)CW?XYEtBhbc`A z_Q(*322^Jhj6oEstI`2vh)r8AKZS$)~S?KRKiJoa^u$0{hzq{~G)!k4Vh zq^PRVsTG%$@C=(U&W?8a7Yu&bWclFm6*+y6ZO&uuh&gJ<_HNYXz+Z z;|C)kv|{Y;i~xJ?D(z5GQ6nckNlxY2Cv~cSxg{{W4ps&GiI1|FH$_6gHAr7klXvot z@MBZejMe1TvV^<(IQG`V*WyW#=S)mb$cOA!RHE|PsS;Jy@P%gc$dRf;(U!$m7jE6< zVqsZtXlTgxT-Z;Yns0t_kyk)qlSU9TI8-IEN2GN5TSH3V z(=7ez%8wpjw^Ob8y zRs9r2d(4B_B>SXS^N=Djc&*8&ckV;NKM-FH5o;evEqG;815YHFvyd#DQhO#=?#QN8O~Gt+0pZoUdwE#>xSA2Qva-90VlWBmG=z|9|2GR z4&vUuXOFChha{3?T3*A%gdJ4Y#xHL&ut~ZK^cx*crhLVmHpGFPYH|}A&^Y6>>Wyzb*S-` z-<>VY2@2ZS^!YPNu%&}e$SJ$e9x+=e|EgVdr88q{RYz<1#^CPKH@6FJF*bLF1!WAd za&iV^@AK^6PYckf4jd^_2=uVC+%n(O+}f&$Ozx7X8>*V-N`_fNB6sch$<#K*b$5Bs z<$2Y*Ip+U*GSMri5C3WIt*WBFTRG>mfKwR`!q1=s0kClQI`L%Nm zHgj`xe=B!qg*M&?ITvzl{ec$~9&MH0-mwx6 zSFNoSg+fiZ->#U0*EVgUrbbpZ+<;PDf1>Sr;{-ZWeWlWP4KK`(sLhDXoR~}t4e(!b zTpn&+WTLcS$#(DU>uuW*dC|gFC-nsX>hf>39w!vxc~;E=G57CBm95rC3Qodek;kVg z68!t^@Ifr>LoLm|#S;lln^jM#^3*e=dvxpRp3je5`wr<=*rUkcHm-s;HldjQ!_+cs zQw258y5o%~sHmbPHld|Um=3E%LM6s$tgbHEV%pKT^@Of+1YgF)HYRS^nE4d*6EuHx zcc1C+Q~sn>lS#ANK+CIgbx{yGgzuZIb~^;M^eij^7``!4obmGe7@!c|ouUfEZZnQE zlWBQuKusS$NJ=4gzl6&uF*E5azbNMc2klSd0j#4HT+hueCO$($QTy&4H42ZjRo;JlUwvNTr-5*F@<3?jNU6D8TV+4N)Du-L z?p1Ajd#UOoTm(ke)-=fWT!%#C7jt8~KX0}d7-R0}6Ya}N+!h<(e)M3%sG$P95#+YE zw%f$)AX%9{QyhZgg#d6lbu9cga?MZQSG|8|BR-xYL{jJ${UZf+u4;cOrB@Z+?!C`o zMwChGx!a7@^}xVhQ27J|P~!xP@F% z&#?ON@F?lbz~F7gP_6_ti#2I43Blf@S4MtHN6mB+aDhsL1|wRN3h$_5FN%kz2kL<%NI=ha#z%L?sV0ybx!@WsmtK%>i72C>9`G@q-;#PDLfN z>1TT8{cW*l`qK+F%P!?_RJx#`sA!7H@MCi`fYG|NA z6TUV?rEddjr-LOwGD>D4cC2ejPE@9SIDzQHvN ztO*c1D61(b87GzJy|zm9g=iLp(a9T+1rHVk(ry!@*VWa9wWJ!9mOVO`!(58|8C%{c zCEo=d%zZpvGb2wrBS)u0k=H=Wr&^s7aNP5#{5JBVmv{RI>GVwXzY}wt-VNQOUt%IJ zv8o7{liTzV8TzpV{LR$U0-LrNH1|CR8VHsw&wcI+(!z$uFxN4(6#&*>c9pxMw)lRt{8sbp8UTVAPn7vTUGC^dgR!q@e@2et6yC)C zSG%bG3s(l@7zCMnDu#vD>;&h6nw(SxlA^z<^?#ZzN=nKYDfh#;e)QY6(U4-q?0GSK z?KT=idY7?p)v(*MtETA*GjOvuZsCt?YwOUu)^W?6?nhPv8VU9=^)P|R>=8FxUWHaA zN$&Gl+)!nTksKTxNCc+%ty35qq6XqgG7%AxKTVi^-ru{hQ$!a=uX^e7Wj+ZB4)8n> z{Z)ZJC_eth{-OztIo4(x_0`o0^+gPEV)pAmsl7s4Wd6XlJN)g$M9=XogYvC#SP%+r zf03AY9r_KVwX%0fiDgm(rRKbXg48zc<Lj(1`7ql915bz)X6RO-(|*FK35tetV>H zLi$3bJ2lL6Q1pco#n{J>^oVzar^h9$bUl;gM7ntTLHF%d=a2tn{P14AAmV~#di~xw zmIFtQD8hjTnGpr4_}cFj{Zg!Sr0sx{FVq2Z)XfDHf2|(mrAmpJ@#R1eb~l~6=X3wsP`ZdT~8t^sA%ac-^9?}P|K*{|L>B^ zN=r>Z)^9)|iN-eU{(XYrAMGmF``Xpos>3$9TgplnVI<-M*BgA+OTyK+*_%%*$V9>w zMS=zwlM|>N9UZ&-`utHoZu+?o3yq75Yv@~v2%Z+c+_JYs;yETBB&4TrgtYBRYAPb+ zRzNj!i;CQy6nF}yU)8HuloHOP-L&fOjQpsiwV3|;>;}2Lvub9qEupb{>b2sQWmsu2 zZ$0*{q~<4fdiT>LRDmP<-071Oe3 zI9Q3axOPWRw1un)0ym(m!n6(!B)48#x6ghXog^lL@7%fj;K9!AsJT$$w);R_jp> zz=LEk&y7)Fy7Zd-@8#d<+LN6$28|LA4;-Hs*k|x8Cio2134Vh?C8~5&Vf9*8qbQxO z-;H{D&rZCmWGDGxasd&eu;__mqhh|7y2L42V^2*b^=s7DlLW-fDbB1CwO^LN{iEzb z%oBJlAVb1B*zj12<3ry=tq&^AS5=gi>9=mZ1yrqXGU+w3CsVu+aAxn*B`3ixx{*{f zrx_KO@0^wm7u!u1LGA54JY)!kZ1A0GXPqNM=paq$+;vDyD6Rg`l~Yf5B&l8WpnCIi z1m_$AfuZ+`D9X6_gal}vmKj0FKTLmiUu$V|5o6GkS5Z^-f-BdCTQAqP^x~q6xejfo zU3Mm6We_hC?2J z-ae(A;(!CsV84$Mz3lYJ2}Y~qUiBeM7;FKCnE4O=UtkfirzhRb@}b)4Xm&QX_@_Cv zF9YZzuNYaGY*G)gs(kzUbzKq~TG3fE0}q<<*$iUWrk>Osgz7dF!Ke>2V#6PlYec?KZdGY3CB({rhFPS=OC6;% zqO!9%t!iEdF}+*iwg6=5=kFg$Ng2v569`}rA^L|zNg$>FCQ+1ES|i(zYo(6ZYju>n ze#5w#TI^BRi?gUVfC~6juB|?J9eL}u)@xeMuzU9t9n0NH7hN^a-9a)bb$KsuWn~rH z2xq}|ozTJD@oy#Mh@L$wzvHMLS2otyGm2jvwy21ndjwU;Qy>%2h$KL|e-4Tp3?|bg zRuinrL`R<7dP6dGuZ-ERcv>;R-Rd);s$U8(^D}eK>E!5#J&-E4Xnb6JwSSX~k*Is$ z{;Itz?Qh;}Kydtva)DX=>TpU*3UU3+3(jhvK&E2YvV{_O62uNrXdA|8Do4K1+}HZ@ zB?VBGOW@wx68JX}dd!j|XpSX=-T{KmFawxk5WrbHou~(lsfCZkNqU!-g^he3S zEUjPWwOOrBjVE$tZEaPnA@g9r*P)R%&ldJI^X@a})=K}W1(59`-)mT*uOuQYTs6bd z+CP#^T#++pmvS;L9%P5ovu9*v6Dun#5X|oSeeU8hPJf5RppOQ$x6)u{Y5gZL*Pr)LZ|J4nU3q(d|{5*|P zQEk&>qxv6vV3vN#YUsi9q(s%B+JZ^C7NOaWXV_19Vb5hMr>gU^-)Sc8C#|n5=L1x3 zMiaZ5J!)@z`SNWLQi}7IM-CiNk4b!(q4wO+$I{a5tu}wMdCB{X>Gd(U%-5e%Q+o~I zfB*Nl*T_=Z&p0QX^U#+h{MdmSVgCNLDu!S6-F74#rud1ShThKz-|=guw+yNKvzkl* zG`d99#-%gjLB>Bg5I>S=t^KiSE>gz(eZ1Vtq_I`5q7D1ZS?6!wu+=~sdmLC}z#Ohk zA8nTT!w3FfqVmtnvWp2LC8we?-7PUDdgu`0>?h_xNMxU0&-BpmArb4P3_|5|kHmEQ zs>v_Y-D>aC-%60vBQyp#X557DZbuQMX)*C|%FXT~pcL>+$d_ir_!Ui^wqr!kOjJ)O zLzz=T*+nQZ!ZAl!cd+PUGl;Bx9x`xF=L42RZD2%s?mj?0dBQduaM?HpmsGj z`*Y=PqUdCUq1WZP>GH+I6xOHb?tom{JEeEM!gI04w2(@9 z$IcA~ochT#R#w+K%|AR0it}1bZ_sBaWLU%>p;zrj$Rp5dU|c|QX)wgGMDp}w$spLB zm6A1hj8NG0hn&bd_jH~2$_%TCi3wo6K%~-=?J0>vRK3T2=r zQN0j6%3==0)4u`w8xg(f5Rn5UL9iKP1k2S})JexLUVI`VRDi{PE>*V`xW5flP=hXvyb0g$ncO)!K|lRkZKD9TU%fE z1NucknW$$kea++P!f1pSOJilI&>WIm&b~G(=dCwiux`!a#8~7I4B9-#AD)1&u!h?m z%!NG0$(9`ZU1yY%I46W55CkQVkXIfV*;?-If?*DF{NX(??10AbRoc-j`x+JJJIu(q z{^Q3*W>(g|*i4hD}W^2_|X&GCwjT=QcD)eD z)-j#Q+3DfoLBDO;I;yFOkL|yK|2i=`xI<`b^sg*N>^a*#Hbx9XlysdSVOY07G!nF! zez_Y9rn5G#9(6-auv$P(1*4oU*|qCB@m&(lRkOmn)o$8BSYgXJ=rX3y%*g*$m0)QdTCpeb4b^4o&mZ)APly zceWk9m#wONR7@|34^IpwSU4NbSi=>ha+wgp?AuDCciOu`^?cCgD+2y zD?WLWvim~r;~Z%&mMw%CORZ`L?@Ud}Q7cOF^%*n>ZcnsbPosvFm7l&k$b4G%^fX#g z$%&wwYqANfc3U(knIdbx9|;1VS)P{RD?dD_8sRc|NkfCNVsS(e8sAOeCwu`#aGy&Z ztCrWI^8iE%-nb>>mB5A6k&N$|4Mm3wd7$xGmmz&{viG8)P$}vlSOk3mewiX>6L}c( zcrH^iIf=&npQMb{%*iCjM;V!3xd#m&y9QNLG$)5`G}|I%aEItYVNfOcpl2g6XX}a5 zt*W3qYH`a5G#L5bZtUAp3_77Dd=0|YMt*6_GFxtM0p;3_*FdcJ2(@fXY-|swR# z!`7{vfL0wY)um$U*Z0BT*qfWb+tLq&jT0ovY?naMDmaoVXm^TT#<|4XoNK@)60Q@H z&$+#?rmFhIAZsNVp>>Q|d+$NWci@`(TIwX&{>;W7@;?~hSvOiR0`<9r*jr=VnG81F%XnY#*@7t)bgl1`G9_k`=Uf;OkIZ|s5<7kt4eUbQHb zxYoPFt9^wDDj;geXo<>9iH>^nakvGEGM>sy!Ux+tYqK78ko-FQ!oyn<>x1O|Wa!p{ z+-634FxUi)hS<#99vJqH8OK6|G1+Dj$FpCWHnsP3_18CS-}kR+=bXM}P+9Ei=34Xq z{pORb;dvJ0To0vO3Tu8DG#ml;U%9f%LCYn6^TClTCJ5bH`!f>{YxXZ`Yet{qI6}OZ zgv+m&LE*c$Z@JCD%=|>7GsD#RIIl)-*ha0@?7cwIiB=wPJ9Ij7moDx0T3c~BT#TMj zBS^D{am$uKbXsDePA7_TI=hE^g0`uL+@&R{MD6vBO=sWw#nuPdsa^jR3y&1SEdl-bTTWoJD`;vmgCs#=eAiB#3^WQtX5Ejs;r63L2b6YdK$lTlT`g<;h3n-%PR(S>L_tZRUEFzlA!^kC@^yH9!~XVVfh?M$ z=ny_4qS$vLcoI_>_!iGRQ+7K0g;IWcAXs%bYD?@v0heeh?pnjw|2KW2_5T5Vf_#Ou zK%|M{jL@XNm}$`~22_P|0-XZ`E9(sgz7s~k>BPL2U6W7nD|-t8xan~}xr33QuFq-i z`PV%}DMAB&fK%Mj=lOHd#o1rfVMJ>3I31HBA z(wAIAZbbVU8o0kZ1;cfQ$0NhScszti#cneh`U@%M%!&?*MuBS&;% zD)UPj7__v9_2l9z_e(8eE}IhodVNo4O;Zc;_d^hPzp8ADXcR0xnWeoKz?Ku_HZr{Cke;qK%$dQyZ z19|!SHy85{zPpV{PJR%&^@0c>nDy}=Y47-$l3w3=)t>jf*kj=!V9Jj;=?K8ZnQIqK z+6O=9@n75w9TGK(Kp*r|N;V85+0HvJ6b*Hz9s#q5*^K_6559JEMC+xZE(VoK49AlF zz2*G@ptL#FSnHSH#1W`)obH}acTf?zPu? z{9maG|KhcqH;4M|HeKyq<>O7%R^tWfuY&Y$ZxG+Cm}aN#zW!yH?1x3 z_n#IM^GAd$%C8skK9!eovY3$MYB4c0zdW(M*Iog@UPj2811}yv zf5891=iguQZ=$A~0;#&=1Apo$m=QYEr9sb z)AxXmy@?VaH#k2*f z4g4rvCK^YD9&-~Np|eTv`WSi9vF{yg>quD==lalmfVKBQ048*~(Cc@jR3IRVZB$}% zNM~Qifb!ow%0(WlN%@nuW$1gQ4Duq01OY+JuLF8H51ZolC`T*pM4*`$oE0KuQBY?N zb(Kpr(m@GEPzfCfdCV*g$ zY;Gbw{9ZnWi+a`d2$lMK0nbi3Y<#Tgb?D0kqjQZ2Da(Pw)%d+n*?LEo;ou>dZSZX} zq$-&6<8yOE5of2zIyvB|sF9c*M^R73!u2^>#(mPsN?8EjZ>rjqK$LO{kdfH^9ys;q zsv=OQ6#}91Q{}G(#P}3h06YZbO+A|fa;-3 zA4!lJUc&SlV46BT2QDlYuo|*5Gspjf%YSKdz|qO+n%DNf>bpXflPAeY(?473fO*Fp zvSdX3=pGoLJbt|PYUt;+)g?MmNN5>Ro%=t2%mvCE%}+d1EKt1Z0UBcgyqk5J7jJtY(5J`Hbts%K7$;U>2{H8J+3j z4l2N#K%57Nx1>PI9t8oFv!5fM9d3{hX|#3W!xs2kEyV*u-L6% zV0OHN?h@%jsiQ1reEwOIh!)K!`gYwBa`?v1!I9)yHhanZD@}@d%20c@pza}CUqF&c zX=xkU60IRfxDzML)%ksl7HePl@Ihe0lw&f*q1Nh$fo^R*a^(&RO$;|(S6W(1XeV+X zmtUV!j$Sd5vX#y*sY1!T!d(H051V?j>gU3J~M(1O`feyQp$LRDV zo~xFvrrC{{ADm<_ee{C4k&(}itI4gc zu8@(W+^6Mx+g>X7XJ6vb`h6|dMr-DCP8{1AdIt4JI%+!Hp_^`l@0c4=kPcF0t$7aOaKeS=P~Q?w*JF95=3e|f)Xn89`KN; zJ~+JDqVbUebZ`yt-!tTkKdG@%jvmIyNi`ugw9VTO3NS+UtZ}Vl--Dv=(UJlJn>@Yi z;j41@xrhP1u3o9v56IRNsVYqXEc&HOm%5j3j;m{E_^CaV_C2M@fw6hiB`#M3rkj3B z8-~XDBvv_V3tI_@YG1@U>eSJw2ZoWjjwp?aMaITO}h>!?D z7q(`}44i)Sd3#BOd>bMh(lHek>LL-_=(1D8jiA}D-)-hmQd07fJxh+klBT#f0ydY; zECaAyQN32Gt_ara#1blu_3NJ&VGge@egDmfoZonJ0YQ2G@W=%ihRr7)_XT4tnx0ZC zghB;lKo+}y^#_mhRVV__jq6()?8sdQUYiiV@|*QT=Cf>qvutYm z_|&v*Pm5rE5pSlyj%i5awn%3h28K^RTb>?&t=vd!uusMT*)ahTC+^fd4cs~M_&O-u z2#^v&KI&mYcZAY2U=ESpRbzqz6HjiWr0_RgNihzY+g2jUVsln}1$va1{VLIu^OL4G zZ`VQCbmp2~s@lT|SeCmNpZ_FOVSqK$h)dl_4p&lQX_hXRuGYD88%S&z9EYtz$V!Jq zn~vlBF9v$H?N8K}Jhn=&{5T5-s#E&O?u(aVA5#r6=_%w&_2i*!Bjg!e6 zIrWN42REQpW5y!H%JWk5Zwa=pXNs0GtP3hT{`_*1=DWsijpVnCYj2dR2VWcN=AmRH zf>y5<6|*hlUyuE~^@(VB?@$}X{~d%7I{!VO{S}-3`Sh2=aK~6vXp|TdN|X!YF4xRf z0#`ykvq~2!m$o#w8`U&?Q9WlZ(Pq;0@}!cQip9InmnGOiAQdzW0))(+me&=}t@1fG zx@gIouh1rGe3pIu#c$fKYlEDJDG>TmeFh_OtV+)uA^aJHBxq{7eRSTQY6oM`Hw&

xw;ajoK_n!>>t9yDR?SSQq(DheU#Z1&Ft7 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 bHS+LVGW;hfJ1kN0kxnX{md}wh^80@Pf_rPC literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/images/extract_result.png b/doc/salome/gui/GEOM/images/extract_result.png new file mode 100644 index 0000000000000000000000000000000000000000..4148d0d97d6df2c8ee295a359df3a3da9d15e092 GIT binary patch literal 2941 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 VN4sC5)=*=>-NnOperations -> Extract and Rebuild. +The following dialog box appears: + +\image html extract_rebuild.png "Extract and Rebuild Dialog" + +In this dialog: +

    +
  • \b Name is a result object name.
  • +
  • Main Object is the main object selected for the operation. It is +possible to select the object in the Object Browser or in the viewer using +"selection" button.
  • +
  • Sub-shape type is the type filter for sub-shapes to be chosen +for the extraction.
  • +
  • Filtered shapes is the list of filtered sub-shape IDs available +for the extraction.
  • +
  • Shapes to extract is the list of sub-shape IDs to be extracted +grouped by shape types.
  • +
  • \b >> is the button to copy object IDs from Filtered shapes to +Shapes to extract.
  • +
  • \b << is the button to copy object IDs from Shapes to extract to +Filtered shapes.
  • +
  • Show Only Selected is the button to show objects selected in the +Filtered shapes list and hide all other objects.
  • +
  • Hide Selected is the button to hide objects selected in the +Filtered shapes list.
  • +
  • Show all sub-shapes is the button to show all objects from the +Filtered shapes list.
  • +
  • \b Rebuild is the button to perform extraction and show the operation +statistics.
  • +
  • The block of \b Statistics shows how many shapes of a certain type +are \b Removed, \b Modified and \b Added.
  • +
  • \b Apply is the button to create the result.
  • +
  • Apply and Close is the button to create the result and close +the dialog.
  • +
  • \b Close is the button to close this dialog.
  • +
  • \b Help is the button to show this help page.
  • +
+ +TUI Command: geompy.MakeExtraction(theShape, theListOfID), +
where \em theShape is the main shape, \em theListOfID is a list of +sub-shape IDs to be extracted. + +Our TUI Scripts provide you with useful example of the use of +\ref swig_MakeExtraction "Extract and Rebuild" functionality. + +More details + +If a sub-shape is extracted, all its ancestors should be modified. An ancestors +of extracted sub-shapes can be either: +- created anew without extracted sub-shapes, or +- extracted if it is not possible to create a valid shape without extracted +sub-shape. + +E.g. it is necessary to extract the vertex from the box: + +\image html extract_init.png "Extraction of the vertex from the box" + +In this case 3 ancestor edges are removed as they can't be valid without +this vertex. 3 faces that contain these edges are also removed. It is because +the wires without edges are not closed and it is not possible to create +a valid face on not closed wire. These wires should contain two remaining +edges, but they are removed as they are the part of the remaining shell. +So these wires become empty that means that they should be removed as well. + +The shell is replaced by another one that contains 3 not modified faces. As +It is not possible to construct a valid solid from not closed shell the solid +is removed. So the result of the extraction is a shell that contains 3 faces: + +\image html extract_result.png "Result shape" + +Please, refer to this document for a detailed +description of Extract and Rebuild operation. + +*/ diff --git a/doc/salome/gui/GEOM/input/related_docs.doc b/doc/salome/gui/GEOM/input/related_docs.doc index fea4ba010..2f210676c 100644 --- a/doc/salome/gui/GEOM/input/related_docs.doc +++ b/doc/salome/gui/GEOM/input/related_docs.doc @@ -7,4 +7,6 @@ that can be useful for reading. General Fuse Algorithm, Partition Algorithm, Boolean Operations Algorithm. Backgrounds. +Extract and Rebuild algorithm specification. + */ diff --git a/doc/salome/gui/GEOM/input/transforming_geom_objs.doc b/doc/salome/gui/GEOM/input/transforming_geom_objs.doc index 8ded8676a..3a1307360 100644 --- a/doc/salome/gui/GEOM/input/transforming_geom_objs.doc +++ b/doc/salome/gui/GEOM/input/transforming_geom_objs.doc @@ -27,6 +27,8 @@ special case of \b Explode operation. special case of \b Explode operation.
  • \subpage transfer_data_page "Transfer Data" operation, which copies non-topological data from one shape to another.
  • +
  • \subpage extract_and_rebuild_page "Extract and Rebuild" operation, which +extracts sub-shapes from the main shape.
  • \subpage restore_presentation_parameters_page "Restore presentation parameters". diff --git a/doc/salome/gui/GEOM/input/tui_test_all.doc b/doc/salome/gui/GEOM/input/tui_test_all.doc index 5ed1334a0..7c2ddd136 100644 --- a/doc/salome/gui/GEOM/input/tui_test_all.doc +++ b/doc/salome/gui/GEOM/input/tui_test_all.doc @@ -105,6 +105,9 @@ \until geompy.GetSubShapeEdgeSorted(Sketcher3d_2, p3, "OrderedEdges") \anchor swig_GetSubShapesWithTolerance +\until geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_LE, 1.e-7, "le") + +\anchor swig_MakeExtraction \until print "DONE" */ diff --git a/doc/salome/gui/GEOM/static/ExtractAndRebuild.pdf b/doc/salome/gui/GEOM/static/ExtractAndRebuild.pdf new file mode 100644 index 0000000000000000000000000000000000000000..36e4110575f2d9406e0141b23b0d1ef0f1ab9ed9 GIT binary patch literal 51279 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 L+}X1iJtzGiVkoT* literal 0 HcmV?d00001 diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index be4adbbd0..777f3bcc3 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -2782,6 +2782,43 @@ module GEOM in comparison_condition theCondition, in double theTolerance); + /** + * This enumeration represents an extraction statistics type. It is used in + * the interface GEOM_IShapesOperations::MakeExtraction. + */ + enum ExtractionStatType + { + EST_Removed, ///< Removed sub-shapes + EST_Modified, ///< Modified sub-shapes + EST_Added ///< Newly created sub-shapes + }; + + /*! + * This structure defines a format of extraction statistics. It is used in + * the interface GEOM_IShapesOperations::MakeExtraction. + */ + struct ExtractionStat + { + ExtractionStatType type; ///< Type of extraction statistics. + ListOfLong indices; ///< Shape indices touched by this type of modification. + }; + + typedef sequence ExtractionStats; + + /*! + * \brief Return the shape that is constructed from theShape without + * extracted sub-shapes from the input list. + * + * \param theShape the original shape. + * \param theSubShapeIDs the list of sub-shape IDs to be extracted from + * the original shape. + * \param theStats the operation statistics. Output parameter. + * \return the shape without extracted sub-shapes. + */ + GEOM_Object MakeExtraction(in GEOM_Object theShape, + in ListOfLong theSubShapeIDs, + out ExtractionStats theStats); + }; // # GEOM_IBlocksOperations: diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index b08b1d5b9..ed5809964 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -94,6 +94,7 @@ SET( _res_files edgeextension.png erase.png eraseall.png + extract.png extruded_boss.png extruded_cut.png facetosurface.png diff --git a/resources/extract.png b/resources/extract.png new file mode 100644 index 0000000000000000000000000000000000000000..cdbe85a83aa372ea6a754730285f7629f3145ccf GIT binary patch literal 1155 zcmV-}1bq96P)PKXQnfh-U}4UO^Ij_CGnwNi4T4R<&6*F z2hk@Jec(ZTFh2NTqDB&ocadUh8xTrMOQkKHPN#F`oH>_$S<43)Lx`yV=k@<(trg(E zBIKwVefnH@@a)?{*A7u{>kh!_W5@r6s>;UH>*3)y-qe$4PD@p-ku3|iJ%6oS`SMfh zu6_YOqkqGP3IcJK_-Poi%ak;y?RIXn9 z+He2Y`0CUzPKi z4GvLUR@p0tvWdvjWkqE&$&63|0F&Rb&XF=1Y#yL7)CkYG`N~VRwczkbMbw9fq4Xg3 zmZhj=TRfR=1vgV&xhy7JduPd-c%5C*Ww1}~Z^*RG5ahU`3$BI{ID8^s36G2k*%%&% zs@EZ;1Pg)jq7dQk9g%Nz!|#S>P!^f-o=ak4fV=WO=wo<8Bx{kAjcTuimc3kvP6w1_ zkU~Ie4K@bF#s-SzWpJ}8vOLpXL{*ZNs)u4Q#r+==d&h7YIaB2V7S4LuB!OwQ5NHhu zf$a8eq&IFLTVIC>hEQY{-dko8#LNsJ>w{e|d*s_a$<~t>A$b=Ob70aGyuJ>XBuJK) zkT;v~)`A6*H)Y8-E6FAW`@#ZneXt~(7oMD#E-3;LxaDX_9iUw9>vjd@Im$Rj9>*w* zK~qJ%G(6=4SN6O~9GS$!W*GqA2SMd-hupZgk^&(E`lkL2*|N?rcCTZfZwc!4kd`Gj zgBs6{p2Sb%Pcb)l*p-=JB4U@d03dkaWe6(M2>0wqSl=t8j=Y=*Hycj|nKRtztU;!` zVvRKYGIENqj=caA=S*cn-lUGoc!PQy7h#j{`ye>G_Zt^&f*u%$stt*-Q6*?>SNGdI z2-(`6n5!RgbG75H>}A56jD5bF`gG%#@7($XdGkF0_HPh?gX!F)cy)_e4vJ`SL`WHs zv)rnT`Ne^0w`sgD(wJP4SeLhBAFo{Yt%VD)$!7q%51-tR1(_A@-kxWZXrTv25kv#b z2z;5qq)pf|vA(yp>9-fYqV^x}g53`Ql0NV#2ml12#l4L=idSP6dYtv(Fqu@k^qz6M zD~ql<_aSHZJ^-)?z&>35C$OK4ZFwXe*tEe VwNZ}DIrIPk002ovPDHLkV1g-N85{rr literal 0 HcmV?d00001 diff --git a/src/GEOMAlgo/CMakeLists.txt b/src/GEOMAlgo/CMakeLists.txt index d2b6024ab..38126e94b 100755 --- a/src/GEOMAlgo/CMakeLists.txt +++ b/src/GEOMAlgo/CMakeLists.txt @@ -59,6 +59,7 @@ SET(GEOMAlgo_HEADERS GEOMAlgo_DataMapOfPassKeyInteger.hxx GEOMAlgo_DataMapOfShapeMapOfShape.hxx GEOMAlgo_DataMapOfShapePnt.hxx + GEOMAlgo_Extractor.hxx GEOMAlgo_FinderShapeOn.hxx GEOMAlgo_FinderShapeOn1.hxx GEOMAlgo_FinderShapeOn2.hxx @@ -123,6 +124,7 @@ SET(GEOMAlgo_SOURCES GEOMAlgo_ClsfSurf.cxx GEOMAlgo_CoupleOfShapes.cxx GEOMAlgo_FinderShapeOn2.cxx + GEOMAlgo_Extractor.cxx GEOMAlgo_GetInPlace.cxx GEOMAlgo_GetInPlace_1.cxx GEOMAlgo_GetInPlace_2.cxx diff --git a/src/GEOMAlgo/GEOMAlgo_Extractor.cxx b/src/GEOMAlgo/GEOMAlgo_Extractor.cxx new file mode 100644 index 000000000..bdbadab69 --- /dev/null +++ b/src/GEOMAlgo/GEOMAlgo_Extractor.cxx @@ -0,0 +1,1429 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_Extractor.cxx +// Created: +// Author: Sergey KHROMOV +// + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//======================================================================= +//function : GEOMAlgo_Extractor +//purpose : +//======================================================================= +GEOMAlgo_Extractor::GEOMAlgo_Extractor() +{ +} + +//======================================================================= +//function : ~GEOMAlgo_Extractor +//purpose : +//======================================================================= +GEOMAlgo_Extractor::~GEOMAlgo_Extractor() +{ +} + +//======================================================================= +//function : SetShape +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::SetShape(const TopoDS_Shape &theShape) +{ + myShape = theShape; + myMapShapeAnc.Clear(); + clear(); +} + +//======================================================================= +//function : SetShapesToRemove +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::SetShapesToRemove + (const TopTools_ListOfShape &theSubShapes) +{ + mySubShapes.Assign(theSubShapes); + clear(); +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::Perform() +{ + clear(); + myErrorStatus = 0; + // + checkData(); + + if(myErrorStatus) { + return; + } + + if (myWarningStatus == 10) { + // The result is the same shape. Nothing is modified. + myResult = myShape; + return; + } + + // Mark sub-shapes as removed and modified. + markShapes(); + + // Process Edges. + processShapes(TopAbs_EDGE); + + // Process Wires. + processShapes(TopAbs_WIRE); + + // Process Faces. + processShapes(TopAbs_FACE); + + // Process Shells. + processShapes(TopAbs_SHELL); + + // Process Solids. + processShapes(TopAbs_SOLID); + + // Process Comp-Solids. + processShapes(TopAbs_COMPSOLID); + + // Process Compounds. + processShapes(TopAbs_COMPOUND); + + // Make the result. + myResult = makeResult(myShape); + + TopTools_MapOfShape aMapFence; + + makeHistory(myShape, aMapFence); +} + +//======================================================================= +//function : GetResult +//purpose : +//======================================================================= +const TopoDS_Shape &GEOMAlgo_Extractor::GetResult() const +{ + return myResult; +} + +//======================================================================= +//function : clear +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::clear() +{ + myErrorStatus = 1; + myWarningStatus = 0; + myResult.Nullify(); + myRemoved.Clear(); + myModified.Clear(); + myNew.Clear(); + myMapRemoved.Clear(); + myMapModified.Clear(); + myMapNewShapeAnc.Clear(); +} + +//======================================================================= +//function : checkData +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::checkData() +{ + if (myShape.IsNull()) { + myErrorStatus = 10; + return; + } + + if (mySubShapes.IsEmpty()) { + myWarningStatus = 10; + return; + } + + TopTools_ListIteratorOfListOfShape anIter(mySubShapes); + TopTools_IndexedMapOfShape anIndices; + TopTools_MapOfShape aMapFence; + + TopExp::MapShapes(myShape, anIndices); + + while (anIter.More()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + if (aMapFence.Add(aSubShape)) { + // Check if it is a sub-shape of the given shape. + if (!anIndices.Contains(aSubShape)) { + myErrorStatus = 11; + return; + } + + // Check if it is a main shape. + if (aSubShape.IsSame(myShape)) { + myErrorStatus = 12; + return; + } + + anIter.Next(); + } else { + // Remove duplicated index. + mySubShapes.Remove(anIter); + } + } + + if (myMapShapeAnc.IsEmpty()) { + // Fill the map of shapes - ancestors. + makeMapShapeAncestors(myShape); + } + + // Check if there are seam or degenerated edges on faces. + for (anIter.Initialize(mySubShapes); anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + if (aSubShape.ShapeType() == TopAbs_EDGE) { + // Get the list of ancestor wires. + TopTools_ListOfShape anAncWires; + TopTools_ListIteratorOfListOfShape anAncIt; + + if (myMapShapeAnc.IsBound(aSubShape)) { + anAncIt.Initialize(myMapShapeAnc.Find(aSubShape)); + + for (; anAncIt.More(); anAncIt.Next()) { + const TopoDS_Shape &anAncShape = anAncIt.Value(); + + if (anAncShape.ShapeType() == TopAbs_WIRE) { + anAncWires.Append(anAncShape); + } + } + } + + if (!anAncWires.IsEmpty()) { + // Check the ancestor faces. + Standard_Boolean hasFaces = Standard_False; + TopoDS_Edge anEdge = TopoDS::Edge(aSubShape); + + for (anAncIt.Initialize(anAncWires); anAncIt.More(); anAncIt.Next()) { + const TopoDS_Shape &anAncShape = anAncIt.Value(); + + if (anAncShape.ShapeType() == TopAbs_FACE) { + TopoDS_Face aFace = TopoDS::Face(anAncShape); + + if (BRepTools::IsReallyClosed(anEdge, aFace)) { + // Deletion of face's seam edge is not allowed + myErrorStatus = 13; + return; + } + + hasFaces = Standard_True; + } + } + + if (hasFaces && BRep_Tool::Degenerated(anEdge)) { + myErrorStatus = 14; + return; + } + } + } + } +} + +//======================================================================= +//function : makeMapShapeAncestors +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::makeMapShapeAncestors(const TopoDS_Shape &theShape) +{ + if (theShape.ShapeType() == TopAbs_VERTEX) { + // Vertex is the lowest type. It has no ancestors. + return; + } + + TopoDS_Iterator anIter(theShape); + TopTools_MapOfShape aMapFence; + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + if (aMapFence.Add(aSubShape)) { + // Add theShape as an ancestor shape. + if (!myMapShapeAnc.IsBound(aSubShape)) { + myMapShapeAnc.Bind(aSubShape, TopTools_ListOfShape()); + } + + myMapShapeAnc.ChangeFind(aSubShape).Append(theShape); + + // Recursively call this method for a sub-shape. + makeMapShapeAncestors(aSubShape); + } + } +} + +//======================================================================= +//function : markShapes +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::markShapes() +{ + TopTools_ListIteratorOfListOfShape anIter(mySubShapes); + + // Mark sub-shapes as removed. + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + markRemoved(aSubShape); + } + + // Mark undestors of sub-shapes as modified. + for (anIter.Initialize(mySubShapes); anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + markAncestorsModified(aSubShape); + } +} + +//======================================================================= +//function : markRemoved +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::markRemoved(const TopoDS_Shape &theShape) +{ + if (myMapRemoved.Add(theShape)) { + // Check sub-shapes. + TopoDS_Iterator anIter(theShape); + TopTools_MapOfShape aMapFence; + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + if (aMapFence.Add(aSubShape)) { + TopTools_ListIteratorOfListOfShape anAncIt + (myMapShapeAnc.Find(aSubShape)); + Standard_Boolean isToRm = Standard_True; + + for (; anAncIt.More(); anAncIt.Next()) { + const TopoDS_Shape &anAncShape = anAncIt.Value(); + + if (!myMapRemoved.Contains(anAncShape)) { + isToRm = Standard_False; + break; + } + } + + if (isToRm) { + // Mark sub-shape as removed. + markRemoved(aSubShape); + } + } + } + } +} + +//======================================================================= +//function : markAncestorsModified +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::markAncestorsModified(const TopoDS_Shape &theShape) +{ + if (myMapShapeAnc.IsBound(theShape)) { + TopTools_ListIteratorOfListOfShape anAncIt(myMapShapeAnc.Find(theShape)); + + for (; anAncIt.More(); anAncIt.Next()) { + const TopoDS_Shape &anAncShape = anAncIt.Value(); + + if (!myMapRemoved.Contains(anAncShape) && + !myMapModified.IsBound(anAncShape)) { + // Mark anAncShape as modified. + myMapModified.Bind(anAncShape, TopTools_ListOfShape()); + + // Mark its ancestors as modified. + markAncestorsModified(anAncShape); + } + } + } +} + +//======================================================================= +//function : processShapes +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::processShapes(const TopAbs_ShapeEnum &theType) +{ + TopExp_Explorer anExp(myShape, theType); + TopTools_MapOfShape aMapFence; + + for (; anExp.More(); anExp.Next()) { + TopoDS_Shape aShape = anExp.Current(); // Copy + + if (aMapFence.Add(aShape)) { + if (myMapRemoved.Contains(aShape) || + !myMapModified.IsBound(aShape)) { + // Skip removed or not modified shape. + continue; + } + + aShape.Orientation(TopAbs_FORWARD); + + switch(theType) { + case TopAbs_EDGE: + processEdge(aShape); + break; + case TopAbs_WIRE: + processWire(aShape); + break; + case TopAbs_FACE: + case TopAbs_SOLID: + processFOrSo(aShape); + break; + case TopAbs_SHELL: + case TopAbs_COMPSOLID: + processShOrCS(aShape); + break; + case TopAbs_COMPOUND: + processCompound(aShape); + break; + default: + break; + } + } + } + + if (theType == TopAbs_FACE || theType == TopAbs_SOLID) { + // Clear duplicated edges from the faces and faces from solids + removeBoundsOnFOrSo(theType); + } +} + +//======================================================================= +//function : processEdge +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::processEdge(const TopoDS_Shape &theEdge) +{ + TopoDS_Iterator anIter(theEdge); + TopTools_MapOfShape aMapFence; + TopTools_ListOfShape aVtxList; + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aShapeVertex = anIter.Value(); + + if (aMapFence.Add(aShapeVertex)) { + if (myMapRemoved.Contains(aShapeVertex)) { + // This vertex is removed. + const TopAbs_Orientation anOri = aShapeVertex.Orientation(); + + if (anOri == TopAbs_FORWARD || anOri == TopAbs_REVERSED) { + // This edge will disappear from the result. + return; + } + } else { + // This vertex is not removed. + aVtxList.Append(aShapeVertex); + } + } + } + + TopoDS_Shape aNewEdge = makeShape(theEdge, aVtxList); + + myMapModified.ChangeFind(theEdge).Append(aNewEdge); +} + +//======================================================================= +//function : processWire +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::processWire(const TopoDS_Shape &theWire) +{ + // Get parent face for the wire. + TopoDS_Face aFace; + + if (myMapShapeAnc.IsBound(theWire)) { + TopTools_ListIteratorOfListOfShape anIter(myMapShapeAnc.Find(theWire)); + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aParent = anIter.Value(); + + if (aParent.ShapeType() == TopAbs_FACE) { + aFace = TopoDS::Face(aParent.Oriented(TopAbs_FORWARD)); + break; + } + } + } + + TopoDS_Wire aWire = TopoDS::Wire(theWire); + BRepTools_WireExplorer anExp(aWire, aFace); + NCollection_List aListListEdges; + TopTools_ListOfShape aListEdges; + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Edge &anEdge = anExp.Current(); + + if (myMapRemoved.Contains(anEdge)) { + // This edge is removed. + if (!aListEdges.IsEmpty()) { + aListListEdges.Append(aListEdges); + aListEdges.Clear(); + } + } else if (myMapModified.IsBound(anEdge)) { + // This edge is modified. + TopTools_ListOfShape aModifEdges; + + getModified(anEdge, aModifEdges); + + if (aModifEdges.IsEmpty()) { + // This edge is not created. + if (!aListEdges.IsEmpty()) { + aListListEdges.Append(aListEdges); + aListEdges.Clear(); + } + } else { + const TopoDS_Shape aModifEdge = oriented(aModifEdges.First(), anEdge); + + aListEdges.Append(aModifEdge); + } + } else { + // Get an edge as it is. + aListEdges.Append(anEdge); + } + } + + if (!aListEdges.IsEmpty()) { + aListListEdges.Append(aListEdges); + } + + if (!aListListEdges.IsEmpty()) { + TopTools_ListOfShape aListWires; + + makeWires(theWire, aListListEdges, aListWires); + myMapModified.ChangeFind(theWire) = aListWires; + } +} + +//======================================================================= +//function : processFOrSo +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::processFOrSo(const TopoDS_Shape &theFOrSo) +{ + Standard_Boolean isToCreate = Standard_True; + TopTools_ListOfShape aClosedSubShapes; + TopTools_ListOfShape aNewShapes; + TopoDS_Shape anOuterSubShape; + TopAbs_ShapeEnum aShapeType; + TopAbs_ShapeEnum aSubShapeType; + + if (theFOrSo.ShapeType() == TopAbs_FACE) { + aShapeType = TopAbs_FACE; + aSubShapeType = TopAbs_WIRE; + anOuterSubShape = BRepTools::OuterWire(TopoDS::Face(theFOrSo)); + } else { + aShapeType = TopAbs_SOLID; + aSubShapeType = TopAbs_SHELL; + anOuterSubShape = BRepClass3d::OuterShell(TopoDS::Solid(theFOrSo)); + } + + // Process an outer sub-shape. + if (myMapRemoved.Contains(anOuterSubShape)) { + isToCreate = Standard_False; + } else if (myMapModified.IsBound(anOuterSubShape)) { + TopTools_ListOfShape aModifSubShapes; + + getModified(anOuterSubShape, aModifSubShapes); + + // Check if there is a closed direct sub-shape. + TopTools_ListIteratorOfListOfShape anIter(aModifSubShapes); + TopoDS_Shape aClosedSubShape; + + for (isToCreate = Standard_False; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + if (aSubShape.ShapeType() == aSubShapeType && aSubShape.Closed()) { + if (isToCreate) { + // There is another closed sub-shape. NEVERREACHED. + // No need to create a new shape. + isToCreate = Standard_False; + break; + } else { + // Remember the closed sub-shape. + isToCreate = Standard_True; + aClosedSubShape = aSubShape; + } + } + } + + if (isToCreate) { + // Add a closed sub-shape. + const TopoDS_Shape aNewSubShape = + oriented(aClosedSubShape, anOuterSubShape); + + aClosedSubShapes.Append(aNewSubShape); + } + + // Copy shapes to the list of other shapes. + for (anIter.Initialize(aModifSubShapes); anIter.More(); anIter.Next()) { + const TopoDS_Shape aNewShape = oriented(anIter.Value(), anOuterSubShape); + + if (!isToCreate || !aNewShape.IsSame(aClosedSubShape)) { + aNewShapes.Append(aNewShape); + } + } + } else { + aClosedSubShapes.Append(anOuterSubShape); + } + + // Treat holes. + TopoDS_Iterator anIter(theFOrSo); + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + if (aSubShape.IsSame(anOuterSubShape)) { + // Skip an outer sub-shape. + continue; + } + + if (myMapModified.IsBound(aSubShape)) { + // This is a modified sub-shape. + TopTools_ListOfShape aModifSubShapes; + + getModified(aSubShape, aModifSubShapes); + + TopTools_ListIteratorOfListOfShape anIter(aModifSubShapes); + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape aNewShape = oriented(anIter.Value(), aSubShape); + + if (isToCreate) { + if (aNewShape.ShapeType() == aSubShapeType && aNewShape.Closed()) { + // This is a closed sub-shape. + aClosedSubShapes.Append(aNewShape); + } else { + aNewShapes.Append(aNewShape); + } + } else { + aNewShapes.Append(aNewShape); + } + } + } else if (!myMapRemoved.Contains(aSubShape)) { + // The shape is not modified. + if (isToCreate) { + aClosedSubShapes.Append(aSubShape); + } else { + aNewShapes.Append(aSubShape); + } + } + } + + if (isToCreate) { + // Create a new shape. + TopoDS_Shape aNewShape = makeShape(theFOrSo, aClosedSubShapes); + + aNewShapes.Prepend(aNewShape); + } + + if (!aNewShapes.IsEmpty()) { + // Store modified shapes. + myMapModified.ChangeFind(theFOrSo) = aNewShapes; + } +} + +//======================================================================= +//function : processShOrCS +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::processShOrCS(const TopoDS_Shape &theShOrCS) +{ + // Treat sub-shapes. + TopoDS_Iterator anIter(theShOrCS); + TopTools_ListOfShape aNewSubShapes; + TopTools_ListOfShape aNewOtherShapes; + TopAbs_ShapeEnum aSubShapeType; + TopAbs_ShapeEnum aSubSubShapeType; + + if (theShOrCS.ShapeType() == TopAbs_SHELL) { + aSubShapeType = TopAbs_FACE; + aSubSubShapeType = TopAbs_EDGE; + } else { // comp-solid + aSubShapeType = TopAbs_SOLID; + aSubSubShapeType = TopAbs_FACE; + } + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + if (myMapModified.IsBound(aSubShape)) { + TopTools_ListOfShape aModifList; + + getModified(aSubShape, aModifList); + + // Copy shapes to the list of other shapes. + TopTools_ListIteratorOfListOfShape anIter(aModifList); + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape aNewShape = oriented(anIter.Value(), aSubShape); + + if (aNewShape.ShapeType() == aSubShapeType) { + aNewSubShapes.Append(aNewShape); + } else { + aNewOtherShapes.Append(aNewShape); + } + } + } else if (!myMapRemoved.Contains(aSubShape)) { + // Shape is neither removed nor modified. Add it as it is. + if (aSubShape.ShapeType() == aSubShapeType) { + aNewSubShapes.Append(aSubShape); + } else { + aNewOtherShapes.Append(aSubShape); + } + } + } + + // Group sub-shapes via bounds + TopTools_ListOfShape aNewShapes; + + groupViaBounds(theShOrCS, aNewSubShapes, aNewShapes); + aNewOtherShapes.Prepend(aNewShapes); + + if (!aNewOtherShapes.IsEmpty()) { + // Store modified shapes. + myMapModified.ChangeFind(theShOrCS) = aNewOtherShapes; + } +} + +//======================================================================= +//function : processCompound +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::processCompound(const TopoDS_Shape &theCompound) +{ + // Treat sub-shapes. + TopoDS_Iterator anIter(theCompound); + TopTools_ListOfShape aNewSubShapes; + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + if (myMapModified.IsBound(aSubShape)) { + TopTools_ListOfShape aModifList; + + getModified(aSubShape, aModifList); + + // Copy shapes to the list of other shapes. + TopTools_ListIteratorOfListOfShape anIter(aModifList); + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape aNewShape = oriented(anIter.Value(), aSubShape); + + aNewSubShapes.Append(aNewShape); + } + } else if (!myMapRemoved.Contains(aSubShape)) { + // Shape is neither removed nor modified. Add it as it is. + aNewSubShapes.Append(aSubShape); + } + } + + if (!aNewSubShapes.IsEmpty()) { + if (aNewSubShapes.Extent() == 1) { + // Avoid creation of new compound for a single sub-shape. + myMapModified.ChangeFind(theCompound).Append(aNewSubShapes.First()); + } else { + TopoDS_Shape aNewShape = makeShape(theCompound, aNewSubShapes); + + // Store modified shapes. + myMapModified.ChangeFind(theCompound).Append(aNewShape); + } + } +} + +//======================================================================= +//function : removeBoundsOnFOrSo +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::removeBoundsOnFOrSo(const TopAbs_ShapeEnum theType) +{ + // Get bounds on faces or solids. + TopExp_Explorer anExp(myShape, theType); + TopTools_MapOfShape aMapFence; + TopAbs_ShapeEnum aBoundType; + TopAbs_ShapeEnum aComplexBndType; + TopTools_IndexedMapOfShape aMapBounds; + + if (theType == TopAbs_FACE) { + aBoundType = TopAbs_EDGE; + aComplexBndType = TopAbs_WIRE; + } else { // solid + aBoundType = TopAbs_FACE; + aComplexBndType = TopAbs_SHELL; + } + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aShape = anExp.Current(); + + if (aMapFence.Add(aShape)) { + if (myMapRemoved.Contains(aShape)) { + continue; + } + + if (myMapModified.IsBound(aShape)) { + TopTools_ListOfShape aNewShapes; + + getModified(aShape, aNewShapes); + + if (!aNewShapes.IsEmpty()) { + const TopoDS_Shape &aNewShape = aNewShapes.First(); + + if (aNewShape.ShapeType() == theType) { + // Get bounds from the modified shape. + TopExp::MapShapes(aNewShape, aBoundType, aMapBounds); + } + } + } else { + // Get bounds from the original shapes. + TopExp::MapShapes(aShape, aBoundType, aMapBounds); + } + } + } + + // Remove duplicated bounds from the faces or solids + aMapFence.Clear(); + + for (anExp.Init(myShape, theType); anExp.More(); anExp.Next()) { + const TopoDS_Shape &aShape = anExp.Current(); + + if (aMapFence.Add(aShape)) { + if (myMapModified.IsBound(aShape)) { + TopTools_ListOfShape &aNewShapes = + myMapModified.ChangeFind(aShape); + TopTools_ListIteratorOfListOfShape anIter(aNewShapes); + + while (anIter.More()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + Standard_Boolean isToRm = Standard_False; + + if (aSubShape.ShapeType() == aBoundType) { + // edge or face + isToRm = aMapBounds.Contains(aSubShape); + } else if (aSubShape.ShapeType() == aComplexBndType) { + // wire or shell + TopTools_ListOfShape aNewBounds; + Standard_Boolean isModified; + + if (theType == TopAbs_FACE) { + isModified = removeCommonEdges(aSubShape, aMapBounds, aNewBounds); + } else { + isModified = removeCommonFaces(aSubShape, aMapBounds, aNewBounds); + } + + if (isModified) { + myMapModified.Bind(aSubShape, aNewBounds); + aNewShapes.InsertBefore(aNewBounds, anIter); + isToRm = Standard_True; // To remove unmodified bound. + } + } + + if (isToRm) { + aNewShapes.Remove(anIter); + } else { + anIter.Next(); + } + } + } + } + } +} + +//======================================================================= +//function : oriented +//purpose : +//======================================================================= +TopoDS_Shape GEOMAlgo_Extractor::oriented(const TopoDS_Shape &theShape, + const TopoDS_Shape &theContext) +{ + const TopAbs_Orientation aShapeOri = theShape.Orientation(); + const TopAbs_Orientation aContextOri = theContext.Orientation(); + TopoDS_Shape aResult = theShape; + + aResult.Orientation(TopAbs::Compose(aShapeOri, aContextOri)); + + return aResult; +} + +//======================================================================= +//function : makeShape +//purpose : +//======================================================================= +TopoDS_Shape GEOMAlgo_Extractor::makeShape + (const TopoDS_Shape &theShape, + const TopTools_ListOfShape &theSubShapes) +{ + TopoDS_Shape aResult = getShapeFromSubShapes(theShape, theSubShapes); + + if (aResult.IsNull()) { + // Create a new shape. + BRep_Builder aBuilder; + TopTools_ListIteratorOfListOfShape anIter(theSubShapes); + TopTools_MapOfShape aMapFence; + + aResult = theShape.EmptyCopied(); + aMapFence.Clear(); + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + if (aMapFence.Add(aSubShape)) { + aBuilder.Add(aResult, aSubShape); + + // Fill the map of new shape - ancestors. + if (!myMapNewShapeAnc.IsBound(aSubShape)) { + myMapNewShapeAnc.Bind(aSubShape, TopTools_ListOfShape()); + } + + myMapNewShapeAnc.ChangeFind(aSubShape).Append(aResult); + } + } + } + + return aResult; +} + +//======================================================================= +//function : getShapeFromSubShapes +//purpose : +//======================================================================= +TopoDS_Shape GEOMAlgo_Extractor::getShapeFromSubShapes + (const TopoDS_Shape &theShape, + const TopTools_ListOfShape &theSubShapes) +{ + // Fill the map of sub-shapes. + TopTools_ListIteratorOfListOfShape anIter(theSubShapes); + TopTools_MapOfShape aMapSubShapes; + TopoDS_Shape aFirstSubShape = theSubShapes.First(); + TopoDS_Shape aResult; + + for (; anIter.More(); anIter.Next()) { + aMapSubShapes.Add(anIter.Value()); + } + + // Check if such a shape is already created. + if (!aMapSubShapes.IsEmpty()) { + TopTools_MapIteratorOfMapOfShape aMapIt(aMapSubShapes); + Standard_Boolean isFirst = Standard_True; + TopTools_MapOfShape aMapAncs[2]; + Standard_Integer iCur = 0; + Standard_Integer iPrev = 1; + + for (; aMapIt.More(); aMapIt.Next()) { + const TopoDS_Shape &aSubShape = aMapIt.Key(); + + // Switch iCur and iPrev. + iCur = iCur ? 0 : 1; + iPrev = iPrev ? 0 : 1; + + if (myMapNewShapeAnc.IsBound(aSubShape)) { + TopTools_ListIteratorOfListOfShape + anAncIt(myMapNewShapeAnc.Find(aSubShape)); + + if (isFirst) { + // This is a first loop. Just fill the map of ancestors. + for (; anAncIt.More(); anAncIt.Next()) { + aMapAncs[iCur].Add(anAncIt.Value()); + } + } else { + // Add in aMapAnc[iCur] elements that are only in aMapAnc[iPrev]. + for (aMapAncs[iCur].Clear(); anAncIt.More(); anAncIt.Next()) { + const TopoDS_Shape &anAncestor = anAncIt.Value(); + + if (aMapAncs[iPrev].Contains(anAncestor)) { + aMapAncs[iCur].Add(anAncIt.Value()); + } + } + } + + if (aMapAncs[iCur].IsEmpty()) { + // There is no common shape. It means that + // the result should be a new shape. + aMapAncs[iCur].Clear(); + break; + } + } else { + // This is a new sub-shape. So the result shape is new. + aMapAncs[iCur].Clear(); + break; + } + } + + if (!aMapAncs[iCur].IsEmpty()) { + // Get exactly the same shape. + const TopAbs_ShapeEnum aType = theShape.ShapeType(); + + for (aMapIt.Initialize(aMapAncs[iCur]); aMapIt.More(); aMapIt.Next()) { + const TopoDS_Shape &aShape = aMapIt.Key(); + + if (aShape.ShapeType() == aType) { + // Check sub-shapes. + TopoDS_Iterator aSubShIt(aShape); + TopAbs_Orientation aNewOri = TopAbs_FORWARD; + Standard_Boolean isComposedOri = Standard_False; + + for (; aSubShIt.More(); aSubShIt.Next()) { + const TopoDS_Shape &aSubSh = aSubShIt.Value(); + + if (!aMapSubShapes.Contains(aSubSh)) { + // There are another sub-shapes in the ancestor. + break; + } + + if (!isComposedOri && aSubSh.IsSame(aFirstSubShape)) { + // Compose orientaiton. + isComposedOri = Standard_True; + aNewOri = TopAbs::Compose + (aFirstSubShape.Orientation(), aSubSh.Orientation()); + } + } + + if (!aSubShIt.More()) { + // That is the same shape. Compose the orientation. + aResult = aShape; + aResult.Orientation(aNewOri); + break; + } + } + } + } + } + + return aResult; +} + +//======================================================================= +//function : makeResult +//purpose : +//======================================================================= +TopoDS_Shape GEOMAlgo_Extractor::makeResult(const TopoDS_Shape &theShape) +{ + TopoDS_Shape aResult; + + if (!myMapRemoved.Contains(theShape)) { + if (myMapModified.IsBound(theShape)) { + // The shape is modified. + TopTools_ListOfShape aListModif; + + getModified(theShape, aListModif); + + const Standard_Integer aNbShapes = aListModif.Extent(); + + if (aNbShapes == 1) { + aResult = oriented(aListModif.First(), theShape); + } else if (aNbShapes > 1) { + // Build a result as a compound + TopTools_ListIteratorOfListOfShape anIter(aListModif); + BRep_Builder aBuilder; + TopoDS_Compound aCompound; + TopTools_MapOfShape aMapFence; + + aBuilder.MakeCompound(aCompound); + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape aModifShape = oriented(anIter.Value(), theShape); + + if (aMapFence.Add(aModifShape)) { + aBuilder.Add(aCompound, aModifShape); + } + } + + aResult = aCompound; + } + } else { + // The result is not modified shape. + aResult = theShape; + } + } + + return aResult; +} + +//======================================================================= +//function : makeHistory +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::makeHistory(const TopoDS_Shape &theShape, + TopTools_MapOfShape &theMapFence) +{ + if (theMapFence.Add(theShape)) { + Standard_Boolean isKept = Standard_True; + + if (myMapRemoved.Contains(theShape)) { + myRemoved.Append(theShape); + isKept = Standard_False; + } else if (myMapModified.IsBound(theShape)) { + TopTools_ListOfShape aListModif; + + getModified(theShape, aListModif, theShape.ShapeType()); + + Standard_Boolean isModif = !aListModif.IsEmpty(); + const TopAbs_ShapeEnum aType = theShape.ShapeType(); + + if (isModif) { + // Add the new shapes. + TopTools_ListIteratorOfListOfShape anIter(aListModif); + + // Skip the first shape. + for (anIter.Next(); anIter.More(); anIter.Next()) { + myNew.Append(anIter.Value()); + } + } + + if (isModif) { + myModified.Append(theShape); + } else { + myRemoved.Append(theShape); + } + + isKept = Standard_False; + } + + if (!isKept) { + // Collect history for children. + TopoDS_Iterator anIter(theShape); + + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aSubShape = anIter.Value(); + + makeHistory(aSubShape, theMapFence); + } + } + } +} + +//======================================================================= +//function : removeCommonEdges +//purpose : +//======================================================================= +Standard_Boolean GEOMAlgo_Extractor::removeCommonEdges + (const TopoDS_Shape &theWire, + const TopTools_IndexedMapOfShape &theMapEdgesToRm, + TopTools_ListOfShape &theNewWires) +{ + TopExp_Explorer anExp(theWire, TopAbs_EDGE); + NCollection_List aListListEdges; + TopTools_ListOfShape aListEdges; + Standard_Boolean isModified = Standard_False; + TopoDS_Vertex aVtx[2]; + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &anEdge = anExp.Current(); + + if (theMapEdgesToRm.Contains(anEdge)) { + // This edge is removed. + TopExp::Vertices(TopoDS::Edge(anEdge), aVtx[0], aVtx[1]); + + // Skip edges that have same first and last vertices. + if (aVtx[0].IsNull() || !aVtx[0].IsSame(aVtx[1])) { + if (!aListEdges.IsEmpty()) { + aListListEdges.Append(aListEdges); + aListEdges.Clear(); + } + } + + isModified = Standard_True; + } else { + aListEdges.Append(anEdge); + } + } + + if (!aListEdges.IsEmpty()) { + aListListEdges.Append(aListEdges); + } + + if (isModified && !aListListEdges.IsEmpty()) { + // Make wires. + makeWires(theWire, aListListEdges, theNewWires); + } + + return isModified; +} + +//======================================================================= +//function : removeCommonFaces +//purpose : +//======================================================================= +Standard_Boolean GEOMAlgo_Extractor::removeCommonFaces + (const TopoDS_Shape &theShell, + const TopTools_IndexedMapOfShape &theMapFacesToRm, + TopTools_ListOfShape &theNewShells) +{ + TopExp_Explorer anExp(theShell, TopAbs_FACE); + TopTools_ListOfShape aListFaces; + Standard_Boolean isModified = Standard_False; + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aFace = anExp.Current(); + + if (theMapFacesToRm.Contains(aFace)) { + isModified = Standard_True; + } else { + aListFaces.Append(aFace); + } + } + + if (isModified && !aListFaces.IsEmpty()) { + // Create new shells. + groupViaBounds(theShell, aListFaces, theNewShells); + } + + return isModified; +} + +//======================================================================= +//function : makeWires +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::makeWires + (const TopoDS_Shape &theWire, + NCollection_List &theListListEdges, + TopTools_ListOfShape &theWires) +{ + if (theListListEdges.Size() > 1) { + // Check if it is possible to merge first and last lists of edges. + TopoDS_Edge anEdgeFirst = TopoDS::Edge(theListListEdges.First().First()); + TopoDS_Edge anEdgeLast = TopoDS::Edge(theListListEdges.Last().Last()); + TopoDS_Vertex aCommonVtx; + + if (TopExp::CommonVertex(anEdgeFirst, anEdgeLast, aCommonVtx)) { + // Merge First and last lists of edges. + theListListEdges.First().Prepend(theListListEdges.Last()); + // Remove the last list. + NCollection_List::Iterator anIter(theListListEdges); + + for (;anIter.More(); anIter.Next()) { + if (anIter.Value().IsEmpty()) { + theListListEdges.Remove(anIter); + break; + } + } + } + } + + // Create wires. + NCollection_List::Iterator anIter(theListListEdges); + + for (;anIter.More(); anIter.Next()) { + const TopTools_ListOfShape &anEdges = anIter.Value(); + TopoDS_Shape aNewWireShape = makeShape(theWire, anEdges); + TopoDS_Wire aNewWire = TopoDS::Wire(aNewWireShape); + TopoDS_Vertex aV[2]; + + TopExp::Vertices(aNewWire, aV[0], aV[1]); + + if (!aV[0].IsNull() && !aV[1].IsNull()) { + aNewWire.Closed(aV[0].IsSame(aV[1])); + } + + theWires.Append(aNewWire); + } +} + +//======================================================================= +//function : groupViaBounds +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::groupViaBounds + (const TopoDS_Shape &theShape, + const TopTools_ListOfShape &theSubShapes, + TopTools_ListOfShape &theNewShapes) +{ + const Standard_Boolean isShell = theShape.ShapeType() == TopAbs_SHELL; + TopAbs_ShapeEnum aBoundType; + + if (isShell) { + aBoundType = TopAbs_EDGE; + } else { // comp-solid + aBoundType = TopAbs_FACE; + } + + // Group connected sub-shapes. + NCollection_Sequence aGroupedSubShapes; + NCollection_Sequence aBounds; + TopTools_ListIteratorOfListOfShape anIt(theSubShapes); + Standard_Integer i; + + for (; anIt.More(); anIt.Next()) { + // Find a zone a sub-shape is connected to. + const TopoDS_Shape &aSubShape = anIt.Value(); + TColStd_MapOfInteger aMapIndices; + const Standard_Integer aNbZones = aBounds.Size(); + TopExp_Explorer anExp(aSubShape, aBoundType); + Standard_Integer j; + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aSubSubShape = anExp.Current(); + + // Check each zone. + for (i = 1; i <= aNbZones; ++i) { + if (!aMapIndices.Contains(i)) { + if (aBounds.Value(i).Contains(aSubSubShape)) { + // The current sub-shape belongs to this zone. + aMapIndices.Add(i); + break; + } + } + } + } + + if (aMapIndices.IsEmpty()) { + // Create a new zone. + aGroupedSubShapes.Append(TopTools_ListOfShape()); + aBounds.Append(TopTools_MapOfShape()); + aGroupedSubShapes.ChangeLast().Append(aSubShape); + anExp.Init(aSubShape, aBoundType); + + TopTools_MapOfShape &aLastZoneBound = aBounds.ChangeLast(); + + for (; anExp.More(); anExp.Next()) { + aLastZoneBound.Add(anExp.Current()); + } + } else { + // Merge zones. Get the first zone. + for (i = 1; i <= aNbZones; ++i) { + if (aMapIndices.Contains(i)) { + break; + } + } + + // Merge other zones with the first one. + TopTools_ListOfShape &aZoneSubShapes = aGroupedSubShapes.ChangeValue(i); + TopTools_MapOfShape &aZoneBounds = aBounds.ChangeValue(i); + + for (j = i + 1; j <= aNbZones; ++j) { + if (aMapIndices.Contains(j)) { + aZoneSubShapes.Append(aGroupedSubShapes.ChangeValue(j)); + + TopTools_MapIteratorOfMapOfShape aMapIt(aBounds.Value(j)); + + for (; aMapIt.More(); aMapIt.Next()) { + aZoneBounds.Add(aMapIt.Key()); + } + } + } + + // Remove merged zones. + for (j = aNbZones; j > i; --j) { + aGroupedSubShapes.Remove(j); + aBounds.Remove(j); + } + + // Add aSubShape to merged zone. + aZoneSubShapes.Append(aSubShape); + anExp.Init(aSubShape, aBoundType); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aSubSubShape = anExp.Current(); + + if (!aZoneBounds.Add(aSubSubShape)) { + aZoneBounds.Remove(aSubSubShape); + } + } + } + } + + // Construct new shapes from sub-shapes. + const Standard_Integer aNbGroups = aGroupedSubShapes.Size(); + TopTools_ListOfShape aNewSubShapes; + + for (i = 1; i <= aNbGroups; ++i) { + const TopTools_ListOfShape &aListSubShapes = aGroupedSubShapes.Value(i); + + if (!isShell && aListSubShapes.Extent() == 1) { + // Avoid creation of comp-solid with a single solid. + aNewSubShapes.Append(aListSubShapes.First()); + } else { + TopoDS_Shape aNewShape = makeShape(theShape, aListSubShapes); + + if (aBounds.Value(i).IsEmpty()) { + // This is a closed shape. + aNewShape.Closed(Standard_True); + } + + theNewShapes.Append(aNewShape); + } + } + + // Append the list of single solids (if it is filled). + theNewShapes.Append(aNewSubShapes); +} + +//======================================================================= +//function : getModified +//purpose : +//======================================================================= +void GEOMAlgo_Extractor::getModified(const TopoDS_Shape &theShape, + TopTools_ListOfShape &theModifShapes, + const TopAbs_ShapeEnum theShapeType) +{ + // This shape is modified. + TopTools_ListIteratorOfListOfShape anIt(myMapModified.Find(theShape)); + + for (; anIt.More(); anIt.Next()) { + const TopoDS_Shape &aSubShape = anIt.Value(); + + if (theShapeType == TopAbs_SHAPE || aSubShape.ShapeType() == theShapeType) { + if (myMapModified.IsBound(aSubShape)) { + getModified(aSubShape, theModifShapes); + } else { + theModifShapes.Append(aSubShape); + } + } + } +} + + +// +// myErrorStatus : +// +// 10 -myShape=NULL +// 11 -mySubShapes contains not only sub-shapes of myShape. +// 12 -Can't remove the main shape. +// 13 -mySubShapes contains seam edges in context of faces. +// 14 -mySubShapes contains degenerated edges in context of faces. +// +// myWarningStatus : +// +// 10 -mySubShapes is empty +// diff --git a/src/GEOMAlgo/GEOMAlgo_Extractor.hxx b/src/GEOMAlgo/GEOMAlgo_Extractor.hxx new file mode 100644 index 000000000..9e9215334 --- /dev/null +++ b/src/GEOMAlgo/GEOMAlgo_Extractor.hxx @@ -0,0 +1,363 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_Extractor.hxx +// Author: Sergey KHROMOV + +#ifndef _GEOMAlgo_Extractor_HeaderFile +#define _GEOMAlgo_Extractor_HeaderFile + + +#include + +#include +#include +#include +#include +#include + +class TopTools_IndexedMapOfShape; + + +/** + * \brief This class encapsulates an algorithm of extraction of sub-shapes + * from the main shape. + */ +class GEOMAlgo_Extractor : public GEOMAlgo_Algo +{ +public: + + /** + * \brief Empty constructor. + */ + Standard_EXPORT GEOMAlgo_Extractor(); + + /** + * \brief Virtual destructor. + */ + Standard_EXPORT virtual ~GEOMAlgo_Extractor(); + + /** + * \brief This method sets the main shape. + * + * \param theShape the main shape. + */ + Standard_EXPORT void SetShape(const TopoDS_Shape &theShape); + + /** + * \brief This method returns the main shape. + * + * \return the main shape. + */ + const TopoDS_Shape &GetShape() const + { return myShape; } + + /** + * \brief This method sets the list of sub-shapes to be removed + * from the main shape. + * + * \param theSubShapes the sub-shapes to be removed. + */ + Standard_EXPORT void SetShapesToRemove + (const TopTools_ListOfShape &theSubShapes); + + /** + * \brief This method returns the list of sub-shapes to be removed + * from the main shape. + * + * \return the list of sub-shapes to be removed. + */ + const TopTools_ListOfShape &GetShapesToRemove() const + { return mySubShapes; } + + /** + * This method performs computation of the extracted shape. + */ + Standard_EXPORT virtual void Perform(); + + /** + * This method returns the result of the algorithm. + * + * \return the result of the operation. + */ + Standard_EXPORT const TopoDS_Shape &GetResult() const; + + /** + * \brief This method returns the sub-shapes removed from the main shape. + * + * \return the list of removed sub-shapes. + */ + const TopTools_ListOfShape &GetRemoved() const + { return myRemoved; } + + /** + * \brief This method returns the sub-shapes modified in the main shape. + * + * \return the list of modified sub-shapes. + */ + const TopTools_ListOfShape &GetModified() const + { return myModified; } + + /** + * \brief This method returns the newly created sub-shapes in the result + * shape. + * + * \return the list of new sub-shapes in result. + */ + const TopTools_ListOfShape &GetNew() const + { return myNew; } + +private: + + /** + * \brief This method reinitializes the shape. + */ + void clear(); + + /** + * \brief This method checks the input data. + */ + void checkData(); + + /** + * \brief This method fills the map of shapes and ancestors for the whole + * sub-shapes of theShape. This method is recursively called up to the lowest + * level of sub-shapes i.e. vertices. + * + * \param theShape the shape. + */ + void makeMapShapeAncestors(const TopoDS_Shape &theShape); + + /** + * \brief This method marks shapes to be removed and to be modified. + */ + void markShapes(); + + /** + * \brief This method marks theShape to be removed. If it is required, it + * recursively marks its sub-shapes to be removed. + * + * \param theShape the shape. + */ + void markRemoved(const TopoDS_Shape &theShape); + + /** + * \brief This method marks ancestors of theShape to be modified. It is + * recursively called up to the level of main shape. + * + * \param theShape the shape. + */ + void markAncestorsModified(const TopoDS_Shape &theShape); + + /** + * \brief This method performs computation of modified shapes of + * the provided type. + * + * \param theType the processed shape type. + */ + void processShapes(const TopAbs_ShapeEnum &theType); + + /** + * \brief This method performs computation of a modified edge. + * + * \param theEdge the modified edge (should be forward). + */ + void processEdge(const TopoDS_Shape &theEdge); + + /** + * \brief This method performs computation of a modified wire. + * + * \param theWire the modified wire (should be forward). + */ + void processWire(const TopoDS_Shape &theWire); + + /** + * \brief This method performs computation of a modified face or solid. + * + * \param theFOrSo the modified face or solid (should be forward). + */ + void processFOrSo(const TopoDS_Shape &theFOrSo); + + /** + * \brief This method performs computation of a modified shell or comp-solid. + * + * \param theShOrCS the modified shell or comp-solid (should be forward). + */ + void processShOrCS(const TopoDS_Shape &theShOrCS); + + /** + * \brief This method performs computation of a modified compound. + * + * \param theCompound the modified compound (should be forward). + */ + void processCompound(const TopoDS_Shape &theCompound); + + /** + * \brief This method removes hanging edges (faces) built for faces (solids) + * if they lie on created faces (solids). + * + * \param theType the shape type. Should be either face or solid. + */ + void removeBoundsOnFOrSo(const TopAbs_ShapeEnum theType); + + /** + * \brief Returns theShape with an orientation composed with theContext's + * orientation. + * + * \param theShape the shape to be re-oriented. + * \param theContext the context shape. + */ + TopoDS_Shape oriented(const TopoDS_Shape &theShape, + const TopoDS_Shape &theContext); + + /** + * \brief This method makes a shape as an empty copy of theShape adding + * subshapes to it. + * + * \param theShape the shape to be copied (should be forward). + * \param theSubShapes the sub-shapes (should be oriented correctly). + * \return the modified shape. + */ + TopoDS_Shape makeShape(const TopoDS_Shape &theShape, + const TopTools_ListOfShape &theSubShapes); + + /** + * \brief This method returns the shape from the list of sub-shapes + * if there is any shape created already with these sub-shapes. + * If there is no such shape, null shape is returned. + * + * \param theShape the shape to be copied (should be forward). + * \param theSubShapes the sub-shapes (should be oriented correctly). + * \return the modified shape (or null if it is not found). + */ + TopoDS_Shape getShapeFromSubShapes(const TopoDS_Shape &theShape, + const TopTools_ListOfShape &theSubShapes); + + /** + * \brief This method makes the result for the given shape. If it is removed + * the result is a compound of its modified sub-shapes (or a single + * modified sub-shape if it in only one). + * + * \param theShape the shape. + * \return the result. + */ + TopoDS_Shape makeResult(const TopoDS_Shape &theShape); + + /** + * \brief This method fills the lists of shapes myRemoved, myModified and + * myNew with removed, modified and newly created shapes correspondingly. + * This method is called recursively for sub-shapes of the shape. + * + * \param theShape the shape. + * \param theMapFence the map of already treated shapes. + */ + void makeHistory(const TopoDS_Shape &theShape, + TopTools_MapOfShape &theMapFence); + + /** + * \brief This method removes edges that are in theMapEdgesToRm from + * theWire and re-creates one or more wires from the rest edges. theNewWires + * contains the modified wire(s). + * + * \param theWire the input wire. + * \param theMapEdgesToRm the map of edges to be extracted from theWire. + * \param theNewWires is the list of new wires. Output parameter. + * \return Standard_True if theWire is modified; Standard_False otherwise. + */ + Standard_Boolean removeCommonEdges + (const TopoDS_Shape &theWire, + const TopTools_IndexedMapOfShape &theMapEdgesToRm, + TopTools_ListOfShape &theNewWires); + + /** + * \brief This method removes faces that are in theMapFacesToRm from + * theShell and re-creates one or more shells from the rest faces. + * theNewShells contains the modified shell(s). + * + * \param theShell the input shell. + * \param theMapFacesToRm the map of faces to be extracted from theShell. + * \param theNewShells is the list of new shells. Output parameter. + * \return Standard_True if theShell is modified; Standard_False otherwise. + */ + Standard_Boolean removeCommonFaces + (const TopoDS_Shape &theShell, + const TopTools_IndexedMapOfShape &theMapFacesToRm, + TopTools_ListOfShape &theNewShells); + + /** + * \brief This method creates wires from the list of list of edges. + * + * \param theWire the input wire. + * \param theListListEdges the list of list of edges. Can be modified + * on output. + * \param theWires the list of created wires. Output parameter. + */ + void makeWires(const TopoDS_Shape &theWire, + NCollection_List &theListListEdges, + TopTools_ListOfShape &theWires); + + /** + * \brief This method collects the shapes in theShapes via common bounds. + * This method is used to group faces into shells via common edges or + * solids into compsolids via common faces. Collected lists of shapes + * are used to create new shapes from theShape that are returned in + * theNewShapes. theNewShapes is not cleared at first. + * + * \param theShape the original shape. + * \param theSubShapes the list of shapes to be connected. + * \param theNewShapes the list of newly created shapes. Output parameter. + */ + void groupViaBounds(const TopoDS_Shape &theShape, + const TopTools_ListOfShape &theSubShapes, + TopTools_ListOfShape &theNewShapes); + + /** + * \brief This method returns the list of modified shapes obtained + * from theShape. It performs recursive search in myMapModified. + * theModifShapes is not cleared at first. If theShapeType filter is equal + * to TopAbs_SHAPE (default value) all modified shapes will be returned, + * otherwise shapes of particular type will only be returned. + * + * \param theShape the shape examined. + * \param theModifShapes the list of modified shapes. Output parameter. + * \param theShapeType the shape type filter. + */ + void getModified(const TopoDS_Shape &theShape, + TopTools_ListOfShape &theModifShapes, + const TopAbs_ShapeEnum theShapeType = TopAbs_SHAPE); + +protected: + + TopoDS_Shape myShape; + TopoDS_Shape myResult; + TopTools_ListOfShape mySubShapes; + TopTools_ListOfShape myRemoved; + TopTools_ListOfShape myModified; + TopTools_ListOfShape myNew; + TopTools_DataMapOfShapeListOfShape myMapShapeAnc; + TopTools_MapOfShape myMapRemoved; + TopTools_DataMapOfShapeListOfShape myMapModified; + TopTools_DataMapOfShapeListOfShape myMapNewShapeAnc; + +}; + +#endif diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index cfcccd313..5ec53885f 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -1387,6 +1387,10 @@ ICO_TRANSFER_DATA transfer_data.png + + ICO_EXTRACTION + extract.png + ICO_IMPORT_SHAPE import.png @@ -1407,6 +1411,10 @@ ICON_DLG_TRANSFER_DATA transfer_data.png + + ICON_DLG_EXTRACTION + extract.png + ICON_DLG_SCALE_ALONG_AXES scale_along_axes.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 7aef53a75..efb543e09 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -471,6 +471,10 @@ Please, select face, shell or solid and try again GEOM_COMPOUNDSOLID CompSolid + + GEOM_COMPSOLIDS + CompSolids + GEOM_COMPOUND_TITLE Create A Compound @@ -607,6 +611,10 @@ Please, select face, shell or solid and try again GEOM_EDGE Edge + + GEOM_EDGES + Edges + GEOM_EDGE_TITLE Create An Edge @@ -2024,6 +2032,10 @@ Please, select face, shell or solid and try again GEOM_SOLID Solid + + GEOM_SOLIDS + Solids + GEOM_SOLID_TITLE Solid Construction @@ -5236,6 +5248,18 @@ Please, select face, shell or solid and try again STB_TRANSFER_DATA Transfer Data + + TOP_EXTRACTION + Extract and Rebuild + + + MEN_EXTRACTION + Extract and Rebuild + + + STB_EXTRACTION + Extract and Rebuild + TOP_EXTENSION Extend Edge or Face @@ -7629,4 +7653,55 @@ Do you want to create new material? Rotation angle + + OperationGUI_ExtractionDlg + + GEOM_EXTRACT_TITLE + Extract and Rebuild + + + GEOM_EXTRACT_TYPE + Extraction type + + + GEOM_EXTRACT_INPUT_PARAMS + Input parameters + + + GEOM_EXTRACT_STATISTICS + Statistics + + + GEOM_EXTRACT_SUB_SHAPE_TYPE + Sub-shape type + + + GEOM_EXTRACT_FILTERED_SHAPES + Filtered shapes + + + GEOM_EXTRACT_SHAPES_TO_EXTRACT + Shapes to extract + + + GEOM_EXTRACT_REBUILD + Rebuild + + + GEOM_EXTRACT_REMOVED + Removed + + + GEOM_EXTRACT_MODIFIED + Modified + + + GEOM_EXTRACT_ADDED + Added + + + GEOM_EXTRACT_NAME + Extraction + + diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index a7111b94c..7db35f809 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -471,6 +471,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_COMPOUNDSOLID Assemblage solide + + GEOM_COMPSOLIDS + CompSolids + GEOM_COMPOUND_TITLE Créer un assemblage @@ -607,6 +611,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_EDGE Arête + + GEOM_EDGES + Edges + GEOM_EDGE_TITLE Créer une arête @@ -2016,6 +2024,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_SOLID Solide + + GEOM_SOLIDS + Solids + GEOM_SOLID_TITLE Construction d'un solide @@ -5228,6 +5240,18 @@ Choisissez une face, une coque ou un solide et essayez de nouveau STB_TRANSFER_DATA Transfert de données + + TOP_EXTRACTION + Extract and Rebuild + + + MEN_EXTRACTION + Extract and Rebuild + + + STB_EXTRACTION + Extract and Rebuild + TOP_EXTENSION Extend Edge or Face @@ -7605,4 +7629,55 @@ Voulez-vous en créer un nouveau ? Longueur de l'angle + + OperationGUI_ExtractionDlg + + GEOM_EXTRACT_TITLE + Extract and Rebuild + + + GEOM_EXTRACT_TYPE + Extraction type + + + GEOM_EXTRACT_INPUT_PARAMS + Input parameters + + + GEOM_EXTRACT_STATISTICS + Statistics + + + GEOM_EXTRACT_SUB_SHAPE_TYPE + Sub-shape type + + + GEOM_EXTRACT_FILTERED_SHAPES + Filtered shapes + + + GEOM_EXTRACT_SHAPES_TO_EXTRACT + Shapes to extract + + + GEOM_EXTRACT_REBUILD + Rebuild + + + GEOM_EXTRACT_REMOVED + Removed + + + GEOM_EXTRACT_MODIFIED + Modified + + + GEOM_EXTRACT_ADDED + Added + + + GEOM_EXTRACT_NAME + Extraction + + diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index 0e42dfe3d..667818994 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -467,6 +467,10 @@ GEOM_COMPOUNDSOLID 固体のアセンブリ + + GEOM_COMPSOLIDS + CompSolids + GEOM_COMPOUND_TITLE コンパウンドの作成 @@ -603,6 +607,10 @@ GEOM_EDGE Edge + + GEOM_EDGES + Edges + GEOM_EDGE_TITLE エッジを作成 @@ -2019,6 +2027,10 @@ GEOM_SOLID ソリッド + + GEOM_SOLIDS + Solids + GEOM_SOLID_TITLE ソリッドの構築 @@ -5231,6 +5243,18 @@ STB_TRANSFER_DATA データ転送 + + TOP_EXTRACTION + Extract and Rebuild + + + MEN_EXTRACTION + Extract and Rebuild + + + STB_EXTRACTION + Extract and Rebuild + TOP_EXTENSION エッジまたは面の拡張 @@ -7598,4 +7622,55 @@ 回転角度 + + OperationGUI_ExtractionDlg + + GEOM_EXTRACT_TITLE + Extract and Rebuild + + + GEOM_EXTRACT_TYPE + Extraction type + + + GEOM_EXTRACT_INPUT_PARAMS + Input parameters + + + GEOM_EXTRACT_STATISTICS + Statistics + + + GEOM_EXTRACT_SUB_SHAPE_TYPE + Sub-shape type + + + GEOM_EXTRACT_FILTERED_SHAPES + Filtered shapes + + + GEOM_EXTRACT_SHAPES_TO_EXTRACT + Shapes to extract + + + GEOM_EXTRACT_REBUILD + Rebuild + + + GEOM_EXTRACT_REMOVED + Removed + + + GEOM_EXTRACT_MODIFIED + Modified + + + GEOM_EXTRACT_ADDED + Added + + + GEOM_EXTRACT_NAME + Extraction + + diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 0d3f733a6..47aeffbf8 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -623,6 +623,7 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) case GEOMOp::OpExtrudedBoss: // MENU OPERATION - EXTRUDED BOSS case GEOMOp::OpExtrudedCut: // MENU OPERATION - EXTRUDED CUT case GEOMOp::OpTransferData: // MENU OPERATION - TRANSFER DATA + case GEOMOp::OpExtraction: // MENU OPERATION - EXTRACT AND REBUILD libName = "OperationGUI"; break; case GEOMOp::OpSewing: // MENU REPAIR - SEWING @@ -1005,6 +1006,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpShapesOnShape, "GET_SHAPES_ON_SHAPE" ); createGeomAction( GEOMOp::OpSharedShapes, "GET_SHARED_SHAPES" ); createGeomAction( GEOMOp::OpTransferData, "TRANSFER_DATA" ); + createGeomAction( GEOMOp::OpExtraction, "EXTRACTION" ); createGeomAction( GEOMOp::OpExtrudedCut, "EXTRUDED_CUT" ); createGeomAction( GEOMOp::OpExtrudedBoss, "EXTRUDED_BOSS" ); createGeomAction( GEOMOp::OpFillet1d, "FILLET_1D" ); @@ -1262,6 +1264,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createMenu( GEOMOp::OpShapesOnShape, operId, -1 ); createMenu( GEOMOp::OpSharedShapes, operId, -1 ); createMenu( GEOMOp::OpTransferData, operId, -1 ); + createMenu( GEOMOp::OpExtraction, operId, -1 ); createMenu( separator(), operId, -1 ); @@ -1438,6 +1441,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createTool( GEOMOp::OpShapesOnShape, operTbId ); createTool( GEOMOp::OpSharedShapes, operTbId ); createTool( GEOMOp::OpTransferData, operTbId ); + createTool( GEOMOp::OpExtraction, operTbId ); int featTbId = createTool( tr( "TOOL_FEATURES" ), QString( "GEOMModification" ) ); createTool( GEOMOp::OpFillet1d, featTbId ); diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index 480b7d2fd..a80c3d093 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -166,6 +166,7 @@ namespace GEOMOp { OpExtrudedBoss = 3709, // MENU OPERATION - ETRUDED BOSS OpExtrudedCut = 3710, // MENU OPERATION - ETRUDED CUT OpTransferData = 3711, // MENU OPERATION - TRANSFER DATA + OpExtraction = 3712, // MENU OPERATION - EXTRACT AND REBUILD // RepairGUI -------------------//-------------------------------- OpSewing = 4000, // MENU REPAIR - SEWING OpSuppressFaces = 4001, // MENU REPAIR - SUPPRESS FACES diff --git a/src/GEOMImpl/CMakeLists.txt b/src/GEOMImpl/CMakeLists.txt index 5c59b2e72..9bdce7d48 100755 --- a/src/GEOMImpl/CMakeLists.txt +++ b/src/GEOMImpl/CMakeLists.txt @@ -79,6 +79,7 @@ SET(GEOMImpl_HEADERS GEOMImpl_ICircle.hxx GEOMImpl_ISpline.hxx GEOMImpl_IEllipse.hxx + GEOMImpl_IExtract.hxx GEOMImpl_IFillet.hxx GEOMImpl_IFillet1d.hxx GEOMImpl_IFillet2d.hxx diff --git a/src/GEOMImpl/GEOMImpl_IExtract.hxx b/src/GEOMImpl/GEOMImpl_IExtract.hxx new file mode 100644 index 000000000..35a2799e4 --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_IExtract.hxx @@ -0,0 +1,73 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +//NOTE: This is an intreface to a function for the Offset creation. +// +#include "GEOM_Function.hxx" +#include + +#define EXTRACT_SHAPE 1 +#define EXTRACT_IDS 2 +#define EXTRACT_REMOVED_IDS 3 +#define EXTRACT_MODIFIED_IDS 4 +#define EXTRACT_ADDED_IDS 5 + +class GEOMImpl_IExtract +{ + public: + + GEOMImpl_IExtract(Handle(GEOM_Function) theFunction): _func(theFunction) {} + + void SetShape(Handle(GEOM_Function) theShape) + { _func->SetReference(EXTRACT_SHAPE, theShape); } + + Handle(GEOM_Function) GetShape() + { return _func->GetReference(EXTRACT_SHAPE); } + + void SetSubShapeIDs(const Handle(TColStd_HArray1OfInteger)& theSubShapeIDs) + { _func->SetIntegerArray(EXTRACT_IDS, theSubShapeIDs); } + + Handle(TColStd_HArray1OfInteger) GetSubShapeIDs() + { return _func->GetIntegerArray(EXTRACT_IDS); } + + void SetRemovedIDs(const Handle(TColStd_HArray1OfInteger)& theRemovedIDs) + { _func->SetIntegerArray(EXTRACT_REMOVED_IDS, theRemovedIDs); } + + Handle(TColStd_HArray1OfInteger) GetRemovedIDs() + { return _func->GetIntegerArray(EXTRACT_REMOVED_IDS); } + + void SetModifiedIDs(const Handle(TColStd_HArray1OfInteger)& theModifiedIDs) + { _func->SetIntegerArray(EXTRACT_MODIFIED_IDS, theModifiedIDs); } + + Handle(TColStd_HArray1OfInteger) GetModifiedIDs() + { return _func->GetIntegerArray(EXTRACT_MODIFIED_IDS); } + + void SetAddedIDs(const Handle(TColStd_HArray1OfInteger)& theAddedIDs) + { _func->SetIntegerArray(EXTRACT_ADDED_IDS, theAddedIDs); } + + Handle(TColStd_HArray1OfInteger) GetAddedIDs() + { return _func->GetIntegerArray(EXTRACT_ADDED_IDS); } + + private: + + Handle(GEOM_Function) _func; +}; diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index 65716670c..c02c13f4d 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -36,6 +36,7 @@ #include "GEOMImpl_GlueDriver.hxx" #include "GEOMImpl_FillingDriver.hxx" +#include "GEOMImpl_IExtract.hxx" #include "GEOMImpl_IVector.hxx" #include "GEOMImpl_IShapes.hxx" #include "GEOMImpl_IShapeExtend.hxx" @@ -3163,6 +3164,107 @@ Handle(TColStd_HSequenceOfTransient) return aSeq; } +//============================================================================= +/*! + * MakeExtraction + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeExtraction + (const Handle(GEOM_Object) &theShape, + const Handle(TColStd_HArray1OfInteger) &theSubShapeIDs, + std::list &theStats) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) { + return NULL; + } + + //Add a new Result object + Handle(GEOM_Object) aResult = + GetEngine()->AddObject(GetDocID(), GEOM_EXTRACTION); + + //Add a new Extraction function + Handle(GEOM_Function) aFunction = + aResult->AddFunction(GEOMImpl_ShapeDriver::GetID(), EXTRACTION); + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) { + return NULL; + } + + Handle(GEOM_Function) aShape = theShape->GetLastFunction(); + + if (aShape.IsNull()) { + return NULL; + } + + GEOMImpl_IExtract aCI (aFunction); + + aCI.SetShape(aShape); + aCI.SetSubShapeIDs(theSubShapeIDs); + + //Compute the Edge value + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Shape driver failed"); + + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + + return NULL; + } + + // Fill in statistics. + theStats.clear(); + + Handle(TColStd_HArray1OfInteger) aStatIDsArray[3] = + { aCI.GetRemovedIDs(), aCI.GetModifiedIDs(), aCI.GetAddedIDs() }; + int i; + int j; + + for (j = 0; j < 3; ++j) { + if (!aStatIDsArray[j].IsNull()) { + const int anUpperID = aStatIDsArray[j]->Upper(); + ExtractionStat aStat; + + for (i = aStatIDsArray[j]->Lower(); i <= anUpperID; ++i) { + aStat.indices.push_back(aStatIDsArray[j]->Value(i)); + } + + aStat.type = (ExtractionStatType) j; + theStats.push_back(aStat); + } + } + + //Make a Python command + GEOM::TPythonDump pd(aFunction); + + pd << aResult << " = geompy.MakeExtraction(" << theShape << ", ["; + + if (!theSubShapeIDs.IsNull()) { + const int aNbIDs = theSubShapeIDs->Upper(); + + for (i = theSubShapeIDs->Lower(); i < aNbIDs; ++i) { + pd << theSubShapeIDs->Value(i) << ", "; + } + + // Dump the last value without a comma. + pd << theSubShapeIDs->Value(i); + } + + pd << "])"; + + SetErrorCode(OK); + + return aResult; +} + //======================================================================= //function : getShapesOnSurfaceIDs /*! diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index d8e4f9fb2..38b375059 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -59,6 +59,25 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations All = Groups | Fields | SubShapes, }; + /** + * This enumeration represents an extraction statistics type. + */ + enum ExtractionStatType + { + EST_Removed, ///< Removed sub-shapes + EST_Modified, ///< Modified sub-shapes + EST_Added ///< Newly created sub-shapes + }; + + /*! + * This structure defines a format of extraction statistics. + */ + struct ExtractionStat + { + ExtractionStatType type; ///< Type of extraction statistics. + std::list indices; ///< Shape indices touched by this type of modification. + }; + Standard_EXPORT GEOMImpl_IShapesOperations(GEOM_Engine* theEngine, int theDocID); Standard_EXPORT ~GEOMImpl_IShapesOperations(); @@ -470,6 +489,21 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations const GEOMUtils::ComparisonCondition theCondition, const Standard_Real theTolerance); + /*! + * \brief Return the shape that is constructed from theShape without + * extracted sub-shapes from the input list. + * + * \param theShape the original shape. + * \param theSubShapeIDs the list of sub-shape IDs to be extracted from + * the original shape. + * \param theStats the operation statistics. Output parameter. + * \return the shape without extracted sub-shapes. + */ + Handle(GEOM_Object) MakeExtraction + (const Handle(GEOM_Object) &theShape, + const Handle(TColStd_HArray1OfInteger) &theSubShapeIDs, + std::list &theStats); + private: Handle(GEOM_Object) MakeShape (std::list theShapes, const Standard_Integer theObjectType, diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 46bcd193e..471fd679b 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -22,6 +22,7 @@ #include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include // OCCT Includes #include @@ -109,6 +111,39 @@ #include +/** + * \brief This static function converts the list of shapes into an array + * of their IDs. If the input list is empty, null handle will be returned. + * this method doesn't check if a shape presents in theIndices map. + * + * \param theListOfShapes the list of shapes. + * \param theIndices the indexed map of shapes. + * \return the array of shape IDs. + */ +static Handle(TColStd_HArray1OfInteger) GetShapeIDs + (const TopTools_ListOfShape &theListOfShapes, + const TopTools_IndexedMapOfShape &theIndices) +{ + Handle(TColStd_HArray1OfInteger) aResult; + + if (!theListOfShapes.IsEmpty()) { + const Standard_Integer aNbShapes = theListOfShapes.Extent(); + TopTools_ListIteratorOfListOfShape anIter(theListOfShapes); + Standard_Integer i; + + aResult = new TColStd_HArray1OfInteger(1, aNbShapes); + + for (i = 1; anIter.More(); anIter.Next(), ++i) { + const TopoDS_Shape &aShape = anIter.Value(); + const Standard_Integer anIndex = theIndices.FindIndex(aShape); + + aResult->SetValue(i, anIndex); + } + } + + return aResult; +} + namespace { // check that compound includes only shapes of expected type @@ -918,6 +953,97 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } } + } else if (aType == EXTRACTION) { + allowCompound = true; + + GEOMImpl_IExtract aCI(aFunction); + Handle(GEOM_Function) aRefShape = aCI.GetShape(); + TopoDS_Shape aShapeBase = aRefShape->GetValue(); + + if (aShapeBase.IsNull()) { + Standard_NullObject::Raise("Argument Shape is null"); + return 0; + } + + Handle(TColStd_HArray1OfInteger) anIDs = aCI.GetSubShapeIDs(); + TopTools_ListOfShape aListSubShapes; + TopTools_IndexedMapOfShape anIndices; + int i; + + TopExp::MapShapes(aShapeBase, anIndices); + + if (!anIDs.IsNull()) { + const int anUpperID = anIDs->Upper(); + const int aNbShapes = anIndices.Extent(); + + for (i = anIDs->Lower(); i <= anUpperID; ++i) { + const Standard_Integer anIndex = anIDs->Value(i); + + if (anIndex < 1 || anIndex > aNbShapes) { + TCollection_AsciiString aMsg(" Invalid index: "); + + aMsg += TCollection_AsciiString(anIndex); + StdFail_NotDone::Raise(aMsg.ToCString()); + return 0; + } + + const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex); + + aListSubShapes.Append(aSubShape); + } + } + + // Compute extraction. + GEOMAlgo_Extractor anExtractor; + + anExtractor.SetShape(aShapeBase); + anExtractor.SetShapesToRemove(aListSubShapes); + + anExtractor.Perform(); + + // Interprete results + Standard_Integer iErr = anExtractor.ErrorStatus(); + + // The detailed description of error codes is in GEOMAlgo_Extractor.cxx + if (iErr) { + TCollection_AsciiString aMsg(" iErr : "); + + aMsg += TCollection_AsciiString(iErr); + StdFail_NotDone::Raise(aMsg.ToCString()); + return 0; + } + + aShape = anExtractor.GetResult(); + + // Get statistics. + const TopTools_ListOfShape &aRemoved = anExtractor.GetRemoved(); + const TopTools_ListOfShape &aModified = anExtractor.GetModified(); + const TopTools_ListOfShape &aNew = anExtractor.GetNew(); + Handle(TColStd_HArray1OfInteger) aRemovedIDs = + GetShapeIDs(aRemoved, anIndices); + Handle(TColStd_HArray1OfInteger) aModifiedIDs = + GetShapeIDs(aModified, anIndices); + Handle(TColStd_HArray1OfInteger) aNewIDs; + + if (!aShape.IsNull()) { + // Get newly created sub-shapes + TopTools_IndexedMapOfShape aNewIndices; + + TopExp::MapShapes(aShape, aNewIndices); + aNewIDs = GetShapeIDs(aNew, aNewIndices); + } + + if (!aRemovedIDs.IsNull()) { + aCI.SetRemovedIDs(aRemovedIDs); + } + + if (!aModifiedIDs.IsNull()) { + aCI.SetModifiedIDs(aModifiedIDs); + } + + if (!aNewIDs.IsNull()) { + aCI.SetAddedIDs(aNewIDs); + } } else { } @@ -1880,6 +2006,15 @@ GetCreationInformation(std::string& theOperationName, AddParam(theParams, "Face", aSE.GetShape()); break; } + case EXTRACTION: + { + GEOMImpl_IExtract aCI (function); + + theOperationName = "EXTRACTION"; + AddParam(theParams, "Main Shape", aCI.GetShape()); + AddParam(theParams, "Sub-shape IDs", aCI.GetSubShapeIDs()); + break; + } default: return false; } diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx index 393b4303c..2e58443ac 100644 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -119,6 +119,8 @@ #define GEOM_TRANSFER_DATA 57 +#define GEOM_EXTRACTION 58 + //GEOM_Function types #define COPY_WITH_REF 1 @@ -316,6 +318,7 @@ #define FACE_UV 17 #define SURFACE_FROM_FACE 18 #define SOLID_FACES 19 +#define EXTRACTION 20 #define ARCHIMEDE_TYPE 1 diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.cc b/src/GEOM_I/GEOM_IShapesOperations_i.cc index 7561d9a16..c6c30b228 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@ -2230,3 +2230,98 @@ GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSubShapesWithTolerance return aSeq._retn(); } + +//============================================================================= +/*! + * MakeExtraction + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeExtraction + (GEOM::GEOM_Object_ptr theShape, + const GEOM::ListOfLong &theSubShapeIDs, + GEOM::GEOM_IShapesOperations::ExtractionStats_out theStats) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + theStats = new GEOM::GEOM_IShapesOperations::ExtractionStats; + GetOperations()->SetNotDone(); + + //Get the reference object + Handle(GEOM_Object) aShape = GetObjectImpl(theShape); + + if (aShape.IsNull()) { + return aGEOMObject._retn(); + } + + const int aNbIDs = theSubShapeIDs.length(); + + if (aNbIDs == 0) { + return aGEOMObject._retn(); + } + + int i; + Handle(TColStd_HArray1OfInteger) anArray = + new TColStd_HArray1OfInteger (1, aNbIDs); + + for (i = 0; i < aNbIDs; i++) { + anArray->SetValue(i + 1, theSubShapeIDs[i]); + } + + //Get Shapes in place of aShapeWhat + std::list aStats; + Handle(GEOM_Object) aResult = + GetOperations()->MakeExtraction(aShape, anArray, aStats); + + if (!GetOperations()->IsDone() || aResult.IsNull()) { + return aGEOMObject._retn(); + } + + // Convert statistics. + const int aNbStats = aStats.size(); + + theStats->length(aNbStats); + + // fill the local CORBA array with values from lists + std::list::const_iterator + anIt = aStats.begin(); + + for (i = 0; anIt != aStats.end(); i++, anIt++) { + GEOM::GEOM_IShapesOperations::ExtractionStat_var aResStat = + new GEOM::GEOM_IShapesOperations::ExtractionStat; + + // Copy type + switch (anIt->type) { + case GEOMImpl_IShapesOperations::EST_Removed: + aResStat->type = GEOM::GEOM_IShapesOperations::EST_Removed; + break; + case GEOMImpl_IShapesOperations::EST_Modified: + aResStat->type = GEOM::GEOM_IShapesOperations::EST_Modified; + break; + case GEOMImpl_IShapesOperations::EST_Added: + aResStat->type = GEOM::GEOM_IShapesOperations::EST_Added; + break; + default: + break; + } + + // Copy the list of IDs + std::list aIDList = anIt->indices; + GEOM::ListOfLong_var aResIDList = new GEOM::ListOfLong; + + aResIDList->length(aIDList.size()); + + std::list::iterator anIDIt = aIDList.begin(); + int j = 0; + + for (; anIDIt != aIDList.end(); j++, anIDIt++) { + aResIDList[j] = *anIDIt; + } + + aResStat->indices = aResIDList; + + theStats[i] = aResStat; + } + + return GetObject(aResult); +} diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.hh b/src/GEOM_I/GEOM_IShapesOperations_i.hh index 0f36a38c3..ff9e417f0 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@ -306,6 +306,11 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i : GEOM::comparison_condition theCondition, CORBA::Double theTolerance); + GEOM::GEOM_Object_ptr MakeExtraction + (GEOM::GEOM_Object_ptr theShape, + const GEOM::ListOfLong &theSubShapeIDs, + GEOM::GEOM_IShapesOperations::ExtractionStats_out theStats); + ::GEOMImpl_IShapesOperations* GetOperations() { return (::GEOMImpl_IShapesOperations*)GetImpl(); } }; diff --git a/src/GEOM_SWIG/GEOM_TestAll.py b/src/GEOM_SWIG/GEOM_TestAll.py index ea862293f..a500a67d4 100644 --- a/src/GEOM_SWIG/GEOM_TestAll.py +++ b/src/GEOM_SWIG/GEOM_TestAll.py @@ -590,5 +590,10 @@ def TestAll (geompy, math): geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_LT, 2.e-7, "lt") geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_LE, 1.e-7, "le") + # MakeExtraction + geompy.MakeExtraction(Box, [13], "Ext_no_face") + geompy.MakeExtraction(Box, [18], "Ext_no_edge") + geompy.MakeExtraction(Box, [16], "Ext_no_vertex") + print "DONE" diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 379105b72..5b74cabdd 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -6661,6 +6661,35 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): RaiseIfFailed("IsSubShapeBelongsTo", self.ShapesOp) return IsOk + ## Perform extraction of sub-shapes from the main shape. + # + # @param theShape the main shape + # @param theListOfID the list of sub-shape IDs to be extracted from + # the main shape. + # @return New GEOM.GEOM_Object, containing the shape without + # extracted sub-shapes. + # + # @ref swig_MakeExtraction "Example" + @ManageTransactions("ShapesOp") + def MakeExtraction(self, theShape, theListOfID, theName=None): + """ + Perform extraction of sub-shapes from the main shape. + + Parameters: + theShape the main shape + theListOfID the list of sub-shape IDs to be extracted from + the main shape. + + Returns + New GEOM.GEOM_Object, containing the shape without + extracted sub-shapes. + """ + # Example: see GEOM_TestAll.py + (anObj, aStat) = self.ShapesOp.MakeExtraction(theShape, theListOfID) + RaiseIfFailed("MakeExtraction", self.ShapesOp) + self._autoPublish(anObj, theName, "Extraction") + return anObj + # end of l4_decompose ## @} diff --git a/src/OperationGUI/CMakeLists.txt b/src/OperationGUI/CMakeLists.txt index 2ff65aed2..7f949c31c 100755 --- a/src/OperationGUI/CMakeLists.txt +++ b/src/OperationGUI/CMakeLists.txt @@ -73,6 +73,7 @@ SET(OperationGUI_HEADERS OperationGUI_ChamferDlg.h OperationGUI_GetShapesOnShapeDlg.h OperationGUI_GetSharedShapesDlg.h + OperationGUI_ExtractionDlg.h OperationGUI_ExtrudedFeatureDlg.h OperationGUI_ClippingDlg.h OperationGUI_TransferDataDlg.h @@ -87,6 +88,7 @@ SET(_moc_HEADERS OperationGUI_ChamferDlg.h OperationGUI_GetShapesOnShapeDlg.h OperationGUI_GetSharedShapesDlg.h + OperationGUI_ExtractionDlg.h OperationGUI_ExtrudedFeatureDlg.h OperationGUI_ClippingDlg.h OperationGUI_TransferDataDlg.h @@ -109,6 +111,7 @@ SET(OperationGUI_SOURCES OperationGUI_FilletDlg.cxx OperationGUI_Fillet1d2dDlg.cxx OperationGUI_ChamferDlg.cxx + OperationGUI_ExtractionDlg.cxx OperationGUI_ExtrudedFeatureDlg.cxx OperationGUI_ClippingDlg.cxx OperationGUI_TransferDataDlg.cxx diff --git a/src/OperationGUI/OperationGUI.cxx b/src/OperationGUI/OperationGUI.cxx index 3288921ab..96e5fc57a 100644 --- a/src/OperationGUI/OperationGUI.cxx +++ b/src/OperationGUI/OperationGUI.cxx @@ -40,6 +40,7 @@ #include "OperationGUI_GetSharedShapesDlg.h" #include "OperationGUI_ExtrudedFeatureDlg.h" // Methods EXTRUDED BOSS / CUT #include "OperationGUI_TransferDataDlg.h" +#include "OperationGUI_ExtractionDlg.h" //======================================================================= // function : OperationGUI() @@ -83,6 +84,7 @@ bool OperationGUI::OnGUIEvent (int theCommandID, SUIT_Desktop* parent) case GEOMOp::OpFillet1d: (new OperationGUI_Fillet1d2dDlg (getGeometryGUI(), parent, true))->show(); break; case GEOMOp::OpFillet2d: (new OperationGUI_Fillet1d2dDlg (getGeometryGUI(), parent, false))->show(); break; case GEOMOp::OpTransferData: (new OperationGUI_TransferDataDlg (getGeometryGUI(), parent))->show(); break; + case GEOMOp::OpExtraction: (new OperationGUI_ExtractionDlg (getGeometryGUI(), parent))->show(); break; default: app->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID)); } diff --git a/src/OperationGUI/OperationGUI_ExtractionDlg.cxx b/src/OperationGUI/OperationGUI_ExtractionDlg.cxx new file mode 100644 index 000000000..47f2e722b --- /dev/null +++ b/src/OperationGUI/OperationGUI_ExtractionDlg.cxx @@ -0,0 +1,1324 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "OperationGUI_ExtractionDlg.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x050300 + #include +#else + /** + * This class is named as QT class as it is introduced since Qt 5.3. + * It should not be compiled when Salome is ported on Qt 5.3. + */ + class QSignalBlocker + { + public: + QSignalBlocker(QObject *object) + : myObject (object), + myIsBlocked (object && object->signalsBlocked()) { + if (myObject) { + myObject->blockSignals(true); + } + } + + ~QSignalBlocker() { + if (myObject) { + myObject->blockSignals(myIsBlocked); + } + } + + private: + QObject *myObject; ///< Blocked object. + bool myIsBlocked; ///< Initial blocked state. + }; +#endif + + +#define ID_ROLE Qt::DisplayRole +#define TYPE_ROLE Qt::UserRole + +static const char* const TMP_STR = "TEMP"; + +static const char* const SINGLE_SHAPE_TYPE_TR_CODES [] = { + "GEOM_COMPOUND", + "GEOM_COMPOUNDSOLID", + "GEOM_SOLID", + "GEOM_SHELL", + "GEOM_FACE", + "GEOM_WIRE", + "GEOM_EDGE", + "GEOM_VERTEX" +}; + +static const char* const PLURAL_SHAPE_TYPE_TR_CODES [] = { + "GEOM_COMPOUND", // Not used + "GEOM_COMPSOLIDS", + "GEOM_SOLIDS", + "GEOM_SHELLS", + "GEOM_FACES", + "GEOM_WIREZ", + "GEOM_EDGES", + "GEOM_VERTEXES" +}; + + +/** + * This static function creates a new list widget item with given ID and + * returns it. + * + * \param theID the item ID. + * \param theListWidget the list widget. + * \return the created list widget item. + */ +static QListWidgetItem *addNewItem(const int theID, + QListWidget *theListWidget) +{ + QListWidgetItem *aResult = new QListWidgetItem; + + aResult->setData(ID_ROLE, theID); + theListWidget->addItem(aResult); + + return aResult; +} + +/** + * This static function creates a new tree widget item as a child of the input + * one with given ID and returns it. + * + * \param theID the item ID. + * \param theParentItem the parent item. + * \return the created tree widget item. + */ +static QTreeWidgetItem *addChildItem(const int theID, + QTreeWidgetItem *theParentItem) +{ + QTreeWidgetItem *aResult = new QTreeWidgetItem; + + aResult->setData(0, ID_ROLE, theID); + theParentItem->addChild(aResult); + + return aResult; +} + +/** + * This static function returns the maximal shape type of sub-shapes stored in + * the input compound. If it is not a compound, it returns TopAbs_SHAPE. + * + * \param theCompound the compound. + * \return the maximal shape type of sub-shapes stored in the input compound. + */ +static TopAbs_ShapeEnum GetMaxShapeTypeInComp(const TopoDS_Shape &theCompound) +{ + TopAbs_ShapeEnum aResult = TopAbs_SHAPE; + + if (theCompound.IsNull() || theCompound.ShapeType() != TopAbs_COMPOUND) { + return aResult; + } + + TopoDS_Iterator anIt(theCompound, Standard_False, Standard_False); + + for (; anIt.More(); anIt.Next()) { + const TopoDS_Shape &aSubShape = anIt.Value(); + + if (aSubShape.IsNull()) { + continue; + } + + // Get the sub-shape type. + TopAbs_ShapeEnum aSubType = aSubShape.ShapeType(); + + if (aSubType == TopAbs_COMPOUND) { + aSubType = GetMaxShapeTypeInComp(aSubShape); + } + + if (aSubType == TopAbs_SHAPE) { + continue; + } + + if (aResult == TopAbs_SHAPE) { + // This is an initialization. + aResult = aSubType; + } else if (aResult > aSubType) { + aResult = aSubType; + } + } + + return aResult; +} + +//================================================================================= +// class : OperationGUI_ExtractionDlg() +// purpose : +//================================================================================= +OperationGUI_ExtractionDlg::OperationGUI_ExtractionDlg + (GeometryGUI* GUI, QWidget* parent) + : GEOMBase_Skeleton (GUI, parent, false), + mySelBtn (0), + myMainShapeEdit (0), + mySubShTypeCompo (0), + myFilteredList (0), + myExtractedTree (0), + myRemovedList (0), + myModifiedList (0), + myAddedList (0), + myRebuildBtn (0), + myIsHiddenMain (false) +{ + QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap( + "GEOM", tr("ICON_DLG_EXTRACTION"))); + QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap( + "GEOM", tr("ICON_SELECT"))); + + setWindowTitle(tr("GEOM_EXTRACT_TITLE")); + + /***************************************************************/ + + mainFrame()->GroupConstructors->setTitle(tr("GEOM_EXTRACT_TYPE")); + mainFrame()->RadioButton1->setIcon( image0 ); + mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton3->close(); + + // Create an input group. + QGroupBox *anInputGrp = new QGroupBox(tr("GEOM_EXTRACT_INPUT_PARAMS"), centralWidget()); + QGridLayout *anInputLayout = new QGridLayout(anInputGrp); + QHBoxLayout *aShapeLayout = new QHBoxLayout(anInputGrp); + QVBoxLayout *aViewBtnsLayout = new QVBoxLayout(anInputGrp); + QVBoxLayout *aMoveBtnsLayout = new QVBoxLayout(anInputGrp); + QLabel *aMainObjLbl = new QLabel(tr("GEOM_MAIN_OBJECT"), anInputGrp); + QLabel *aSubShTypeLbl = new QLabel(tr("GEOM_EXTRACT_SUB_SHAPE_TYPE"), anInputGrp); + QLabel *aFilteredLbl = new QLabel(tr("GEOM_EXTRACT_FILTERED_SHAPES"), anInputGrp); + QLabel *anExtractedLbl = new QLabel(tr("GEOM_EXTRACT_SHAPES_TO_EXTRACT"), anInputGrp); + QPushButton *aShowOnlySelBtn = new QPushButton(tr("SHOW_ONLY_SELECTED"), anInputGrp); + QPushButton *aHideSelBtn = new QPushButton(tr("HIDE_SELECTED"), anInputGrp); + QPushButton *aShowAllBtn = new QPushButton(tr("SHOW_ALL_SUB_SHAPES"), anInputGrp); + QPushButton *anAddBtn = new QPushButton(">>", anInputGrp); + QPushButton *aRemoveBtn = new QPushButton("<<", anInputGrp); + + myRebuildBtn = new QPushButton(tr("GEOM_EXTRACT_REBUILD"), anInputGrp); + mySelBtn = new QPushButton(anInputGrp); + myMainShapeEdit = new QLineEdit(anInputGrp); + mySubShTypeCompo = new QComboBox(anInputGrp); + myFilteredList = new QListWidget(anInputGrp); + myExtractedTree = new QTreeWidget(anInputGrp); + mySelBtn->setIcon(image1); + myMainShapeEdit->setReadOnly(true); + + aShapeLayout->addWidget(mySelBtn); + aShapeLayout->addWidget(myMainShapeEdit); + + aViewBtnsLayout->addStretch(); + aViewBtnsLayout->addWidget(aShowOnlySelBtn); + aViewBtnsLayout->addWidget(aHideSelBtn); + aViewBtnsLayout->addWidget(aShowAllBtn); + aViewBtnsLayout->addStretch(); + + aMoveBtnsLayout->addStretch(); + aMoveBtnsLayout->addWidget(anAddBtn); + aMoveBtnsLayout->addWidget(aRemoveBtn); + aMoveBtnsLayout->addStretch(); + + anInputLayout->setSpacing(6); + anInputLayout->setContentsMargins(9, 9, 9, 9); + anInputLayout->addWidget(aMainObjLbl, 0, 0); + anInputLayout->addLayout(aShapeLayout, 0, 1, 1, 3); + anInputLayout->addWidget(aSubShTypeLbl, 1, 0); + anInputLayout->addWidget(mySubShTypeCompo, 1, 1, 1, 3); + anInputLayout->addWidget(aFilteredLbl, 2, 1); + anInputLayout->addWidget(anExtractedLbl, 2, 3); + anInputLayout->addLayout(aViewBtnsLayout, 3, 0); + anInputLayout->addWidget(myFilteredList, 3, 1); + anInputLayout->addLayout(aMoveBtnsLayout, 3, 2); + anInputLayout->addWidget(myExtractedTree, 3, 3); + anInputLayout->addWidget(myRebuildBtn, 4, 0, 1, 4); + + // Create a statistics group. + QGroupBox *aStatGrp = new QGroupBox(tr("GEOM_EXTRACT_STATISTICS"), centralWidget()); + QGridLayout *aStatLayout = new QGridLayout(aStatGrp); + QLabel *aRemovedLbl = new QLabel(tr("GEOM_EXTRACT_REMOVED"), aStatGrp); + QLabel *aModifiedLbl = new QLabel(tr("GEOM_EXTRACT_MODIFIED"), aStatGrp); + QLabel *anAddedLbl = new QLabel(tr("GEOM_EXTRACT_ADDED"), aStatGrp); + + myRemovedList = new QListWidget(aStatGrp); + myModifiedList = new QListWidget(aStatGrp); + myAddedList = new QListWidget(aStatGrp); + + aStatLayout->setSpacing(6); + aStatLayout->setContentsMargins(9, 9, 9, 9); + aStatLayout->addWidget(aRemovedLbl, 0, 0); + aStatLayout->addWidget(aModifiedLbl, 0, 1); + aStatLayout->addWidget(anAddedLbl, 0, 2); + aStatLayout->addWidget(myRemovedList, 1, 0); + aStatLayout->addWidget(myModifiedList, 1, 1); + aStatLayout->addWidget(myAddedList, 1, 2); + + // Create a main layout. + QVBoxLayout* aLayout = new QVBoxLayout(centralWidget()); + + aLayout->setMargin(0); + aLayout->setSpacing(6); + aLayout->addWidget(anInputGrp); + aLayout->addWidget(aStatGrp); + + // signals and slots connections + connect(anAddBtn, SIGNAL(clicked()), this, SLOT(onAddExtracted())); + connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemoveExtracted())); + connect(aShowOnlySelBtn, SIGNAL(clicked()), this, SLOT(showOnlySelected())); + connect(aHideSelBtn, SIGNAL(clicked()), this, SLOT(hideSelected())); + connect(aShowAllBtn, SIGNAL(clicked()), this, SLOT(showAllSelected())); + + /***************************************************************/ + myHelpFileName = "extract_and_rebuild_page.html"; + + resize(525, 600); + + /* Initialisation */ + Init(); +} + +//================================================================================= +// function : ~OperationGUI_ExtractionDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +OperationGUI_ExtractionDlg::~OperationGUI_ExtractionDlg() +{ + restoreViewer(); +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::Init() +{ + mySelBtn->setCheckable(true); + mySelBtn->setChecked(true); + myFilteredList->setSelectionMode(QAbstractItemView::ExtendedSelection); + myFilteredList->setSortingEnabled(true); + myExtractedTree->setHeaderHidden(true); + myExtractedTree->setSelectionMode(QAbstractItemView::ExtendedSelection); + myExtractedTree->setColumnCount(1); + myRebuildBtn->setEnabled(false); + myRemovedList->setSelectionMode(QAbstractItemView::NoSelection); + myModifiedList->setSelectionMode(QAbstractItemView::NoSelection); + myAddedList->setSelectionMode(QAbstractItemView::NoSelection); + + // Fill in the extracted tree with initial elements. + myTopItems[0] = 0; // No need to create a item for compound. + + int i; + + for (i = 1; i < 8; i++) { + myTopItems[i] = new QTreeWidgetItem; + myTopItems[i]->setText(0, tr(PLURAL_SHAPE_TYPE_TR_CODES[i])); + myTopItems[i]->setData(0, TYPE_ROLE, i); + + myExtractedTree->addTopLevelItem(myTopItems[i]); + myTopItems[i]->setHidden(true); + } + + // signals and slots connections + connect(mySelBtn, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); + connect(mySubShTypeCompo, SIGNAL(currentIndexChanged(int)), + this, SLOT(onShapeTypeChanged())); + connect(myRebuildBtn, SIGNAL(clicked()), this, SLOT(onRebuild())); + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + connect(myFilteredList, SIGNAL(itemSelectionChanged()), + this, SLOT(onListSelectionChanged())); + connect(myExtractedTree, SIGNAL(itemSelectionChanged()), + this, SLOT(onListSelectionChanged())); + + initName(tr("GEOM_EXTRACT_NAME")); + + activateSelection(); + SelectionIntoArgument(); +} + +//================================================================================= +// function : updateSubShTypeCompo() +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::updateSubShTypeCompo() +{ + bool isValid = true; + int anIStart = TopAbs_COMPOUND; + const int anIEnd = TopAbs_VERTEX; + TopoDS_Shape aShape; + + if (GEOMBase::GetShape(myObj, aShape)) { + const TopAbs_ShapeEnum aType = aShape.ShapeType(); + + if (aType == TopAbs_COMPOUND) { + anIStart = GetMaxShapeTypeInComp(aShape); + isValid = anIStart != TopAbs_SHAPE; + } else { + anIStart = aType + 1; + } + } + + QSignalBlocker aBlocker(mySubShTypeCompo); + mySubShTypeCompo->clear(); + + if (isValid) { + int i; + + for (i = anIStart; i <= anIEnd; i++) { + mySubShTypeCompo->addItem(tr(SINGLE_SHAPE_TYPE_TR_CODES[i]), i); + } + + updateFilteredList(); + } + + return isValid; +} + +//================================================================================= +// function : updateFilteredList() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::updateFilteredList() +{ + TopoDS_Shape aShape; + QSignalBlocker aBlocker(myFilteredList); + + myFilteredList->clear(); + + if (GEOMBase::GetShape(myObj, aShape)) { + const TopAbs_ShapeEnum aType = (TopAbs_ShapeEnum) + mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt(); + TopExp_Explorer anExp(aShape, aType); + + if (anExp.More()) { + TopTools_MapOfShape aMapFence; + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aSubShape = anExp.Current(); + + if (!aSubShape.IsNull() && aMapFence.Add(aSubShape)) { + int anIndex = myIndices.FindIndex(aSubShape); + + if (!myMapExtractedIDs.Contains(anIndex)) { + addNewItem(anIndex, myFilteredList); + } + } + } + } + } +} + +//================================================================================= +// function : resetBuildData() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::resetBuildData(const bool isEnableBuild) +{ + // Clear result data. + myRemovedList->clear(); + myModifiedList->clear(); + myAddedList->clear(); + myRebuildBtn->setEnabled(isEnableBuild); +} + +//================================================================================= +// function : isEmptyExtracted() +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::isEmptyExtracted() +{ + bool isEmpty = true; + int i; + + // Check if there are sub-shapes to be extracted. + for (i = 1; i < 8; i++) { + if (!myTopItems[i]->isHidden()) { + isEmpty = false; + + break; + } + } + + return isEmpty; +} + +//================================================================================= +// function : selectMainShape +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::selectMainShape() +{ + LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr(); + SALOME_ListIO aSelList; + + aSelMgr->selectedObjects(aSelList); + + if (aSelList.Extent() == 1) { + GEOM::GEOM_Object_var aSelObject = + GEOMBase::ConvertIOinGEOMObject(aSelList.First()); + TopoDS_Shape aSelShape; + + if (GEOMBase::GetShape(aSelObject, aSelShape)) { + const TopAbs_ShapeEnum aType = aSelShape.ShapeType(); + + // Skip verices. + if (aType != TopAbs_VERTEX) { + myObj = aSelObject; + + // Initialize map of indices. Note that myIndices should be empty. + TopExp::MapShapes(aSelShape, myIndices); + } + } + } + + if (!updateSubShTypeCompo()) { + // Invalid selected object. + myObj = GEOM::GEOM_Object::_nil(); + } + + if (!CORBA::is_nil(myObj)) { + mySelBtn->setChecked(false); + myMainShapeEdit->setEnabled(false); + myMainShapeEdit->setText(GEOMBase::GetName(myObj)); + + // Hide the main object from the viewer. + SALOME_View* aView = GEOM_Displayer::GetActiveView(); + + if (aView) { + CORBA::String_var aMainEntry = myObj->GetStudyEntry(); + Handle(SALOME_InteractiveObject) anIO = createIO(aMainEntry.in()); + + if (aView->isVisible(anIO)) { + GEOM_Displayer *aDisplayer = getDisplayer(); + + aDisplayer->Erase(myObj, false, true); + myIsHiddenMain = true; + } + } + } +} + +//================================================================================= +// function : selectSubShapes +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::selectSubShapes() +{ + QSignalBlocker aBlocker(myFilteredList); + + // Clear current selection. + myFilteredList->clearSelection(); + + LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr(); + SALOME_ListIO aSelList; + const int aCurType = + mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt(); + + aSelMgr->selectedObjects(aSelList); + + // try to find out and process the global selection + // (of not published objects and of published sub-shapes) + SALOME_ListIteratorOfListIO anIter(aSelList); + + for (; anIter.More(); anIter.Next()) { + Handle(SALOME_InteractiveObject) anIObj = anIter.Value(); + QString anEntry = anIObj->getEntry(); + QStringList aParts = anEntry.split("_"); + int aSubShapeId = -1; + + if (!aParts.isEmpty()) { + if (aParts.first() == TMP_STR) { + bool isOk = false; + const int anIndex = aParts.last().toInt(&isOk); + + if (isOk && anIndex > 0) { + // This is a sub-shape. + aSubShapeId = anIndex; + } + } + } + + if (aSubShapeId < 0) { + // This is a published shape. + GEOM::GEOM_Object_var aSelObject = + GEOMBase::ConvertIOinGEOMObject(anIObj); + TopoDS_Shape aSelShape; + + if (GEOMBase::GetShape(aSelObject, aSelShape)) { + + if (aSelShape.ShapeType() == aCurType) { + const int anIndex = myIndices.FindIndex(aSelShape); + + if (anIndex > 0) { + // This is a sub-shape. Select it in the filtered list. + aSubShapeId = anIndex; + } + } + } + } + + // Select a list widget item by Id. + if (aSubShapeId > 0) { + QString anIdText = QString("%1").arg(aSubShapeId); + QList aFound = + myFilteredList->findItems(anIdText, Qt::MatchExactly); + + foreach (QListWidgetItem *anItem, aFound) { + anItem->setSelected(true); + } + } + } +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::ClickOnOk() +{ + if (ClickOnApply()) { + ClickOnCancel(); + } +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::ClickOnApply() +{ + if (!onAccept()) { + return false; + } + + initName(); + + return true; +} + +//================================================================================= +// function : onShapeTypeChanged +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::onShapeTypeChanged() +{ + updateFilteredList(); + eraseAll(); +} + +//================================================================================= +// function : onAddExtracted +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::onAddExtracted() +{ + QList aListSelected = myFilteredList->selectedItems(); + + if (aListSelected.empty()) { + return; + } + + const int aShapeType = + mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt(); + bool isTreeUpdated = false; + + foreach (QListWidgetItem *anItem, aListSelected) { + const int anIndex = anItem->data(ID_ROLE).toInt(); + + if (myMapExtractedIDs.Add(anIndex)) { + addChildItem(anIndex, myTopItems[aShapeType]); + isTreeUpdated = true; + } + + // Remove anItem from the list. + myFilteredList->removeItemWidget(anItem); + delete anItem; + } + + if (isTreeUpdated) { + myTopItems[aShapeType]->sortChildren(0, Qt::AscendingOrder); + + // Reset build data + resetBuildData(true); + } + + myFilteredList->clearSelection(); + myTopItems[aShapeType]->setHidden(false); +} + +//================================================================================= +// function : onRemoveExtracted +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::onRemoveExtracted() +{ + QList aListSelected = myExtractedTree->selectedItems(); + + if (aListSelected.empty()) { + return; + } + + const int aShapeType = + mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt(); + QSet aSetFence; + bool isTreeUpdated = false; + + foreach (QTreeWidgetItem *anItem, aListSelected) { + if (!aSetFence.contains(anItem)) { + aSetFence.insert(anItem); + + QTreeWidgetItem *aParent = anItem->parent(); + + if (aParent) { + const int anIndex = anItem->data(0, ID_ROLE).toInt(); + // This is a ID item. Remove the ID from myMapExtractedIDs. + if (myMapExtractedIDs.Remove(anIndex)) { + // The item is not removed yet. Get parent index. + const int aParentIndex = aParent->data(0, TYPE_ROLE).toInt(); + + if (aShapeType == aParentIndex) { + // Create an item in the filtered list. + addNewItem(anIndex, myFilteredList); + } + + aParent->removeChild(anItem); + delete anItem; + isTreeUpdated = true; + + // Hilde an empty parent item. + if (aParent->childCount() == 0) { + aParent->setHidden(true); + } + } + } else { + // This is a top level item. Remove all its children. + QList aChildItems = anItem->takeChildren(); + const int anIndex = anItem->data(0, TYPE_ROLE).toInt(); + + // Remove IDs from myMapExtractedIDs. + foreach (QTreeWidgetItem *aChild, aChildItems) { + if (!aSetFence.contains(aChild)) { + aSetFence.insert(aChild); + + const int aChildIndex = aChild->data(0, ID_ROLE).toInt(); + + if (myMapExtractedIDs.Remove(aChildIndex)) { + if (aShapeType == anIndex) { + // Create items in the filtered list. + addNewItem(aChildIndex, myFilteredList); + } + + delete aChild; + isTreeUpdated = true; + } + } + } + + // Hilde an empty item. + anItem->setHidden(true); + } + } + } + + myExtractedTree->clearSelection(); + + if (isTreeUpdated) { + // Reset build data + const bool isEnableRebuild = !isEmptyExtracted(); + + resetBuildData(isEnableRebuild); + } +} + +//================================================================================= +// function : onListSelectionChanged +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::onListSelectionChanged() +{ + SALOME_ListIO anIOList; + QList aListSel = myFilteredList->selectedItems(); + QList aTreeSel = myExtractedTree->selectedItems(); + + // Collect selected items from myFilteredList + foreach (QListWidgetItem *anItem, aListSel) { + const int anIndex = anItem->data(ID_ROLE).toInt(); + + if (myMapDisplayedIDs.Contains(anIndex)) { + // Collect only displayed sub-shapes for selection in the viewer. + QString anEntry = getSubShapeEntry(anIndex); + Handle(SALOME_InteractiveObject) anIO = + createIO(anEntry.toLatin1().data()); + + anIOList.Append(anIO); + } + } + + // Collect selected items from myExtractedTree + foreach (QTreeWidgetItem *anItem, aTreeSel) { + if (anItem->parent()) { + // This is a ID item. + const int anIndex = anItem->data(0, ID_ROLE).toInt(); + + if (myMapDisplayedIDs.Contains(anIndex)) { + // Collect only displayed sub-shapes for selection in the viewer. + QString anEntry = getSubShapeEntry(anIndex); + Handle(SALOME_InteractiveObject) anIO = + createIO(anEntry.toLatin1().data()); + + anIOList.Append(anIO); + } + } + } + + // Select object in viewer. + LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr(); + + aSelMgr->setSelectedObjects(anIOList); +} + +//================================================================================= +// function : showOnlySelected +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::showOnlySelected() +{ + TColStd_MapOfInteger aMapIDsSelected; + TColStd_MapOfInteger aMapIDsToDisplay; + const int aNbItems = myFilteredList->count(); + int i; + QSet aSelEntry; + + // Get sub-shape IDs to be displayed. + for (i = 0; i < aNbItems; ++i) { + QListWidgetItem *anItem = myFilteredList->item(i); + const int anIndex = anItem->data(ID_ROLE).toInt(); + + if (anItem->isSelected()) { + aMapIDsSelected.Add(anIndex); + aSelEntry.insert(getSubShapeEntry(anIndex)); + + if (!myMapDisplayedIDs.Contains(anIndex)) { + aMapIDsToDisplay.Add(anIndex); + } + } + } + + // Get sub-shape IDs to be erased. + TColStd_MapOfInteger aMapIDsToHide; + TColStd_MapIteratorOfMapOfInteger anIter(myMapDisplayedIDs); + + for (; anIter.More(); anIter.Next()) { + const int anIndex = anIter.Key(); + + if (!aMapIDsSelected.Contains(anIndex)) { + aMapIDsToHide.Add(anIndex); + } + } + + // Display sub-shapes. + for (anIter.Initialize(aMapIDsToDisplay); anIter.More(); anIter.Next()) { + displaySubShape(anIter.Key()); + } + + // Hide sub-shapes. + for (anIter.Initialize(aMapIDsToHide); anIter.More(); anIter.Next()) { + eraseSubShape(anIter.Key()); + } + + // Hide all objects except already displayed sub-shapes. + SALOME_ListIO aDisplayed; + SALOME_View *aView = GEOM_Displayer::GetActiveView(); + + if (aView) { + aView->GetVisible(aDisplayed); + } + + SALOME_ListIteratorOfListIO aDispIt(aDisplayed); + GEOM_Displayer *aDisplayer = getDisplayer(); + + for (; aDispIt.More(); aDispIt.Next()) { + Handle(SALOME_InteractiveObject) anIO = aDispIt.Value(); + + if (!aSelEntry.contains(anIO->getEntry())) { + aDisplayer->Erase(anIO, false, false); + } + } + + onListSelectionChanged(); + aDisplayer->UpdateViewer(); +} + +//================================================================================= +// function : hideSelected +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::hideSelected() +{ + QList aListSelected = myFilteredList->selectedItems(); + + foreach (QListWidgetItem *anItem, aListSelected) { + const int anIndex = anItem->data(ID_ROLE).toInt(); + + eraseSubShape(anIndex); + } + + getDisplayer()->UpdateViewer(); +} + +//================================================================================= +// function : showAllSelected +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::showAllSelected() +{ + const int aNbItems = myFilteredList->count(); + int i; + + for (i = 0; i < aNbItems; ++i) { + QListWidgetItem *anItem = myFilteredList->item(i); + const int anIndex = anItem->data(ID_ROLE).toInt(); + + displaySubShape(anIndex); + } + + onListSelectionChanged(); + getDisplayer()->UpdateViewer(); +} + +//================================================================================= +// function : onRebuild +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::onRebuild() +{ + GEOM::GEOM_Object_var aResShape; + GEOM::GEOM_IShapesOperations::ExtractionStats aStats; + + if (!getResult(aResShape.out(), aStats)) { + resetBuildData(false); + return; + } + + TopoDS_Shape anOldShape; + TopoDS_Shape aNewShape; + TopTools_IndexedMapOfShape aNewIndices; + + if (!GEOMBase::GetShape(aResShape, aNewShape)) { + resetBuildData(false); + return; + } + + TopExp::MapShapes(aNewShape, aNewIndices); + + const int aNbStat = aStats.length(); + int i; + + for (i = 0; i < aNbStat; ++i) { + // Compute number of sub-shapes of each type. + const int aNbSubShapes = aStats[i].indices.length(); + int aNbShapes [] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int j; + + TopTools_IndexedMapOfShape *aMapShapes = + (aStats[i].type == GEOM::GEOM_IShapesOperations::EST_Added) ? + &aNewIndices : &myIndices; + + for (j = 0; j < aNbSubShapes; ++j) { + const int anIndex = aStats[i].indices[j]; + + if (anIndex < 1 || anIndex > aMapShapes->Extent()) { + resetBuildData(false); + return; + } + + const TopoDS_Shape &aSubShape = aMapShapes->FindKey(anIndex); + + aNbShapes[aSubShape.ShapeType()]++; + } + + // Fill the statistics. + QListWidget *aListWidget = 0; + + switch (aStats[i].type) { + case GEOM::GEOM_IShapesOperations::EST_Removed: + aListWidget = myRemovedList; + break; + case GEOM::GEOM_IShapesOperations::EST_Modified: + aListWidget = myModifiedList; + break; + case GEOM::GEOM_IShapesOperations::EST_Added: + aListWidget = myAddedList; + break; + default: + resetBuildData(false); + return; + } + + QStringList aStrList; + + for (j = 0; j < 8; ++j) { + if (aNbShapes[j] >= 1) { + const char *aShapeType = aNbShapes[j] == 1 ? + SINGLE_SHAPE_TYPE_TR_CODES[j] : PLURAL_SHAPE_TYPE_TR_CODES[j]; + + aStrList.append(QString("%1 %2").arg(aNbShapes[j]).arg(tr(aShapeType))); + } + } + + aListWidget->addItems(aStrList); + } + + myRebuildBtn->setEnabled(false); +} + +//================================================================================= +// function : SelectionIntoArgument +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::SelectionIntoArgument() +{ + if (myMainShapeEdit->isEnabled()) { + // Selection of main object + selectMainShape(); + } else { + // Selection of filtered shapes + selectSubShapes(); + } +} + +//================================================================================= +// function : SetEditCurrentArgument +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::SetEditCurrentArgument() +{ + QSignalBlocker aBlockerList(myFilteredList); + QSignalBlocker aBlockerTree(myExtractedTree); + + restoreViewer(); + myObj = GEOM::GEOM_Object::_nil(); + myMainShapeEdit->setEnabled(true); + myMainShapeEdit->setText(""); + myMainShapeEdit->setFocus(); + + updateSubShTypeCompo(); + + myFilteredList->clear(); + myRemovedList->clear(); + myModifiedList->clear(); + myAddedList->clear(); + myIndices.Clear(); + + // Clear myExtractedTree. + int i; + + for (i = 1; i < 8; i++) { + QList aListItems = myTopItems[i]->takeChildren(); + + foreach (QTreeWidgetItem *anItem, aListItems) { + delete anItem; + } + + myTopItems[i]->setHidden(true); + } + + myExtractedTree->clearSelection(); + + myMapExtractedIDs.Clear(); + + // Update viewer + eraseAll(); +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::ActivateThisDialog() +{ + GEOMBase_Skeleton::ActivateThisDialog(); + + LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr(); + + if (aSel) { + connect(aSel, SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + } + + activateSelection(); +} + +//================================================================================= +// function : activateSelection +// purpose : activate selection of all shapes +//================================================================================= +void OperationGUI_ExtractionDlg::activateSelection() +{ + globalSelection(GEOM_ALLSHAPES); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::enterEvent(QEvent *) +{ + if (!mainFrame()->GroupConstructors->isEnabled()) { + ActivateThisDialog(); + } +} + +//================================================================================= +// function : getResult +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::getResult + (GEOM::GEOM_Object_ptr &theResult, + GEOM::GEOM_IShapesOperations::ExtractionStats &theStats) +{ + if (myObj->_is_nil()) { + return false; + } + + // Get IDs of extracted shapes. + int i; + int aNbShapes = 0; + + for (i = 1; i < 8; i++) { + aNbShapes += myTopItems[i]->childCount(); + } + + if (aNbShapes == 0) { + return false; + } + + GEOM::ListOfLong_var aSubShapeIDs = new GEOM::ListOfLong; + int j; + int jCur; + + aSubShapeIDs->length(aNbShapes); + + for (jCur = 0, i = 1; i < 8; ++i) { + aNbShapes = myTopItems[i]->childCount(); + + for (j = 0; j < aNbShapes; ++j, ++jCur) { + aSubShapeIDs[jCur] = myTopItems[i]->child(j)->data(0, ID_ROLE).toInt(); + } + } + + GEOM::GEOM_IShapesOperations_var anOper = + GEOM::GEOM_IShapesOperations::_narrow(getOperation()); + + try { + GEOM::GEOM_Object_var anObj; + GEOM::GEOM_IShapesOperations::ExtractionStats_var aStats; + + anObj = anOper->MakeExtraction(myObj, aSubShapeIDs, aStats); + + if (anOper->IsDone() && aStats->length() > 0) { + theStats = aStats; + } + + if (!CORBA::is_nil(anObj)) { + theResult = anObj._retn(); + } + } + catch (const SALOME::SALOME_Exception& e) { + SalomeApp_Tools::QtCatchCorbaException(e); + return false; + } + + return anOper->IsDone(); +} + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::isValid(QString &) +{ + bool isOk = !myObj->_is_nil() && !isEmptyExtracted(); + + return isOk; +} + +//================================================================================= +// function : createOperation +// purpose : +//================================================================================= +GEOM::GEOM_IOperations_ptr OperationGUI_ExtractionDlg::createOperation() +{ + return getGeomEngine()->GetIShapesOperations(getStudyId()); +} + +//================================================================================= +// function : execute +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::execute(ObjectList &objects) +{ + GEOM::GEOM_Object_var aResShape; + GEOM::GEOM_IShapesOperations::ExtractionStats aStats; + + if (!getResult(aResShape.out(), aStats)) { + return false; + } + + if (!aResShape->_is_nil()) { + objects.push_back(aResShape._retn()); + } + + return true; +} + +//================================================================================= +// function : getSubShapeEntry +// purpose : +//================================================================================= +QString OperationGUI_ExtractionDlg::getSubShapeEntry(const int theId) +{ + CORBA::String_var aMainEntry = myObj->GetStudyEntry(); + QString anEntry = QString("%1_").arg(TMP_STR) + + aMainEntry.in() + QString("_%1").arg(theId); + + return anEntry; +} + +//================================================================================= +// function : createIO +// purpose : +//================================================================================= +Handle_SALOME_InteractiveObject OperationGUI_ExtractionDlg::createIO + (const char *theEntry) +{ + Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject + (theEntry, "GEOM", "TEMP_IO"); + + return anIO; +} + +//================================================================================= +// function : displaySubShape +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::displaySubShape(const int theId) +{ + if (theId < 1 || theId > myIndices.Extent()) { + return; + } + + // Create a presentation + const TopoDS_Shape &aSubShape = myIndices.FindKey(theId); + QString anEntry = getSubShapeEntry(theId); + SALOME_View *aView = GEOM_Displayer::GetActiveView(); + GEOM_Displayer *aDisplayer = getDisplayer(); + SALOME_Prs *aPrs = aDisplayer->buildSubshapePresentation + (aSubShape, anEntry, aView); + + if (aPrs) { + if (aView) { + aView->Display(aDisplayer, aPrs); + } + + delete aPrs; + + myMapDisplayedIDs.Add(theId); + } +} + +//================================================================================= +// function : eraseSubShape +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::eraseSubShape(const int theId) +{ + QString anEntry = getSubShapeEntry(theId); + Handle(SALOME_InteractiveObject) anIO = + createIO(anEntry.toLatin1().data()); + + getDisplayer()->Erase(anIO, false, false); + myMapDisplayedIDs.Remove(theId); +} + +//================================================================================= +// function : eraseAll +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::eraseAll() +{ + TColStd_MapIteratorOfMapOfInteger anIter(myMapDisplayedIDs); + + for (; anIter.More(); anIter.Next()) { + eraseSubShape(anIter.Key()); + } + + myMapDisplayedIDs.Clear(); + getDisplayer()->UpdateViewer(); +} + +//================================================================================= +// function : restoreViewer +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::restoreViewer() +{ + if (!CORBA::is_nil(myObj)) { + if (myIsHiddenMain) { + getDisplayer()->Display(myObj, false); + myIsHiddenMain = false; + } + + eraseAll(); + } +} diff --git a/src/OperationGUI/OperationGUI_ExtractionDlg.h b/src/OperationGUI/OperationGUI_ExtractionDlg.h new file mode 100644 index 000000000..f10592aa5 --- /dev/null +++ b/src/OperationGUI/OperationGUI_ExtractionDlg.h @@ -0,0 +1,115 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef OPERATIONGUI_EXTRACTIONDLG_H +#define OPERATIONGUI_EXTRACTIONDLG_H + +#include + +#include +#include + +class QComboBox; +class QListWidget; +class QTreeWidget; +class QTreeWidgetItem; + + +//================================================================================= +// class : OperationGUI_ExtractionDlg +// purpose : +//================================================================================= +class OperationGUI_ExtractionDlg : public GEOMBase_Skeleton +{ + + Q_OBJECT + +public: + + OperationGUI_ExtractionDlg( GeometryGUI*, QWidget* ); + ~OperationGUI_ExtractionDlg(); + +protected: + + // redefined from GEOMBase_Helper and MeasureGUI_Skeleton + virtual GEOM::GEOM_IOperations_ptr createOperation(); + virtual bool execute(ObjectList &); + virtual void activateSelection(); + virtual bool isValid( QString& ); + +private slots: + + void SelectionIntoArgument(); + void ClickOnOk(); + bool ClickOnApply(); + void onShapeTypeChanged(); + void onAddExtracted(); + void onRemoveExtracted(); + void onListSelectionChanged(); + void showOnlySelected(); + void hideSelected(); + void showAllSelected(); + void onRebuild(); + void ActivateThisDialog(); + void SetEditCurrentArgument(); + +private: + + void Init(); + bool updateSubShTypeCompo(); + void updateFilteredList(); + void resetBuildData(const bool isEnableBuild); + bool isEmptyExtracted(); + void selectMainShape(); + void selectSubShapes(); + void enterEvent(QEvent *); + bool getResult + (GEOM::GEOM_Object_ptr &theResult, + GEOM::GEOM_IShapesOperations::ExtractionStats &theStats); + QString getSubShapeEntry(const int theId); + Handle_SALOME_InteractiveObject createIO(const char *theEntry); + void displaySubShape(const int theId); + void eraseSubShape(const int theId); + void eraseAll(); + void restoreViewer(); + +private: + + GEOM::GEOM_Object_var myObj; + QPushButton *mySelBtn; + QLineEdit *myMainShapeEdit; + QComboBox *mySubShTypeCompo; + QListWidget *myFilteredList; + QTreeWidget *myExtractedTree; + QListWidget *myRemovedList; + QListWidget *myModifiedList; + QListWidget *myAddedList; + QTreeWidgetItem *myTopItems[8]; + QPushButton *myRebuildBtn; + TColStd_MapOfInteger myMapExtractedIDs; + bool myIsHiddenMain; + TColStd_MapOfInteger myMapDisplayedIDs; + TopTools_IndexedMapOfShape myIndices; + +}; + +#endif // OPERATIONGUI_EXTRACTIONDLG_H From 8370b4a1c488f6ef18d8944869d6a8cd3a2d18d2 Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 15 Mar 2016 15:26:56 +0300 Subject: [PATCH 53/63] Update copyright: 2016 --- AUTHORS | 0 CMakeLists.txt | 2 +- ChangeLog | 0 GEOM_version.h.in | 2 +- INSTALL | 1 - LICENCE | 504 ------------------ NEWS | 0 README | 112 ++++ SalomeGEOMConfig.cmake.in | 2 +- adm_local/CMakeLists.txt | 2 +- adm_local/cmake_files/CMakeLists.txt | 2 +- adm_local/cmake_files/FindGEOM.cmake | 2 +- adm_local/cmake_files/FindSalomeGEOM.cmake | 2 +- adm_local/cmake_files/FindSalomeOpenCV.cmake | 2 +- adm_local/unix/CMakeLists.txt | 2 +- adm_local/unix/config_files/CMakeLists.txt | 2 +- adm_local/unix/config_files/check_GEOM.m4 | 2 +- adm_local/unix/config_files/check_GUI.m4 | 2 +- adm_local/unix/config_files/check_OpenCV.m4 | 2 +- bin/CMakeLists.txt | 2 +- bin/addvars2notebook_GEOM.py | 2 +- bin/geom_setenv.py | 2 +- doc/CMakeLists.txt | 2 +- doc/salome/CMakeLists.txt | 2 +- doc/salome/examples/CMakeLists.txt | 2 +- .../examples/CTestTestfileInstall.cmake | 2 +- doc/salome/examples/testme.py | 2 +- doc/salome/gui/CMakeLists.txt | 2 +- doc/salome/gui/GEOM/CMakeLists.txt | 2 +- doc/salome/gui/GEOM/collect_geom_methods.py | 2 +- doc/salome/gui/GEOM/doxyfile.in | 2 +- doc/salome/gui/GEOM/doxyfile_py.in | 2 +- doc/salome/gui/GEOM/doxyfile_tui.in | 2 +- doc/salome/gui/GEOM/static/footer.html | 2 +- doc/salome/tui/CMakeLists.txt | 2 +- doc/salome/tui/doxyfile.in | 2 +- doc/salome/tui/static/footer.html | 2 +- idl/AdvancedGEOM.idl | 2 +- idl/BREPPlugin.idl | 2 +- idl/CMakeLists.txt | 2 +- idl/GEOM_Gen.idl | 2 +- idl/GEOM_Superv.idl | 2 +- idl/IGESPlugin.idl | 2 +- idl/STEPPlugin.idl | 2 +- idl/STLPlugin.idl | 2 +- idl/VTKPlugin.idl | 2 +- idl/XAOPlugin.idl | 2 +- resources/AdvancedGEOM.xml | 2 +- resources/BREPPlugin.xml | 2 +- resources/CMakeLists.txt | 2 +- resources/GEOMCatalog.xml.in | 2 +- resources/GEOM_en.xml | 2 +- resources/GEOM_fr.xml | 2 +- resources/IGESPlugin.xml | 2 +- resources/STEPPlugin.xml | 2 +- resources/STLPlugin.xml | 2 +- resources/SalomeApp.xml.in | 2 +- resources/VTKPlugin.xml | 2 +- resources/XAOPlugin.xml | 2 +- src/ARCHIMEDE/Archimede_VolumeSection.cxx | 2 +- src/ARCHIMEDE/Archimede_VolumeSection.hxx | 2 +- src/ARCHIMEDE/CMakeLists.txt | 2 +- src/AdvancedEngine/AdvancedEngine.cxx | 2 +- src/AdvancedEngine/AdvancedEngine.hxx | 2 +- .../AdvancedEngine_DividedDiskDriver.cxx | 2 +- .../AdvancedEngine_DividedDiskDriver.hxx | 2 +- .../AdvancedEngine_IDividedDisk.hxx | 2 +- .../AdvancedEngine_IOperations.cxx | 2 +- .../AdvancedEngine_IOperations.hxx | 2 +- .../AdvancedEngine_IOperations_i.cc | 2 +- .../AdvancedEngine_IOperations_i.hh | 2 +- .../AdvancedEngine_IPipeTShape.hxx | 2 +- .../AdvancedEngine_ISmoothingSurface.hxx | 2 +- .../AdvancedEngine_OperationsCreator.cxx | 2 +- .../AdvancedEngine_OperationsCreator.hxx | 2 +- .../AdvancedEngine_PipeTShapeDriver.cxx | 2 +- .../AdvancedEngine_PipeTShapeDriver.hxx | 2 +- .../AdvancedEngine_SmoothingSurfaceDriver.cxx | 2 +- .../AdvancedEngine_SmoothingSurfaceDriver.hxx | 2 +- src/AdvancedEngine/AdvancedEngine_Types.hxx | 2 +- src/AdvancedEngine/CMakeLists.txt | 2 +- src/AdvancedGUI/AdvancedGUI.cxx | 2 +- src/AdvancedGUI/AdvancedGUI.h | 2 +- .../AdvancedGUI_DividedCylinderDlg.cxx | 2 +- .../AdvancedGUI_DividedCylinderDlg.h | 2 +- .../AdvancedGUI_DividedDiskDlg.cxx | 2 +- src/AdvancedGUI/AdvancedGUI_DividedDiskDlg.h | 2 +- src/AdvancedGUI/AdvancedGUI_PipeTShapeDlg.cxx | 2 +- src/AdvancedGUI/AdvancedGUI_PipeTShapeDlg.h | 2 +- .../AdvancedGUI_SmoothingSurfaceDlg.cxx | 2 +- .../AdvancedGUI_SmoothingSurfaceDlg.h | 2 +- src/AdvancedGUI/CMakeLists.txt | 2 +- src/BREPPlugin/BREPPlugin_Engine.cxx | 2 +- src/BREPPlugin/BREPPlugin_Engine.hxx | 2 +- src/BREPPlugin/BREPPlugin_ExportDriver.cxx | 2 +- src/BREPPlugin/BREPPlugin_ExportDriver.hxx | 2 +- src/BREPPlugin/BREPPlugin_GUI.cxx | 2 +- src/BREPPlugin/BREPPlugin_GUI.h | 2 +- src/BREPPlugin/BREPPlugin_IECallBack.cxx | 2 +- src/BREPPlugin/BREPPlugin_IECallBack.hxx | 2 +- src/BREPPlugin/BREPPlugin_IExport.hxx | 2 +- src/BREPPlugin/BREPPlugin_IImport.hxx | 2 +- src/BREPPlugin/BREPPlugin_IOperations.cxx | 2 +- src/BREPPlugin/BREPPlugin_IOperations.hxx | 2 +- src/BREPPlugin/BREPPlugin_IOperations_i.cc | 2 +- src/BREPPlugin/BREPPlugin_IOperations_i.hh | 2 +- src/BREPPlugin/BREPPlugin_ImportDriver.cxx | 2 +- src/BREPPlugin/BREPPlugin_ImportDriver.hxx | 2 +- .../BREPPlugin_OperationsCreator.cxx | 2 +- .../BREPPlugin_OperationsCreator.hxx | 2 +- src/BREPPlugin/CMakeLists.txt | 2 +- src/BasicGUI/BasicGUI.cxx | 2 +- src/BasicGUI/BasicGUI.h | 2 +- src/BasicGUI/BasicGUI_ArcDlg.cxx | 2 +- src/BasicGUI/BasicGUI_ArcDlg.h | 2 +- src/BasicGUI/BasicGUI_CircleDlg.cxx | 2 +- src/BasicGUI/BasicGUI_CircleDlg.h | 2 +- src/BasicGUI/BasicGUI_CurveDlg.cxx | 2 +- src/BasicGUI/BasicGUI_CurveDlg.h | 2 +- src/BasicGUI/BasicGUI_EllipseDlg.cxx | 2 +- src/BasicGUI/BasicGUI_EllipseDlg.h | 2 +- src/BasicGUI/BasicGUI_LineDlg.cxx | 2 +- src/BasicGUI/BasicGUI_LineDlg.h | 2 +- src/BasicGUI/BasicGUI_MarkerDlg.cxx | 2 +- src/BasicGUI/BasicGUI_MarkerDlg.h | 2 +- src/BasicGUI/BasicGUI_ParamCurveWidget.cxx | 2 +- src/BasicGUI/BasicGUI_ParamCurveWidget.h | 2 +- src/BasicGUI/BasicGUI_PlaneDlg.cxx | 2 +- src/BasicGUI/BasicGUI_PlaneDlg.h | 2 +- src/BasicGUI/BasicGUI_PointDlg.cxx | 2 +- src/BasicGUI/BasicGUI_PointDlg.h | 2 +- src/BasicGUI/BasicGUI_VectorDlg.cxx | 2 +- src/BasicGUI/BasicGUI_VectorDlg.h | 2 +- src/BasicGUI/BasicGUI_WorkingPlaneDlg.cxx | 2 +- src/BasicGUI/BasicGUI_WorkingPlaneDlg.h | 2 +- src/BasicGUI/CMakeLists.txt | 2 +- src/BlockFix/BlockFix.cxx | 2 +- src/BlockFix/BlockFix.hxx | 2 +- src/BlockFix/BlockFix_BlockFixAPI.cxx | 2 +- src/BlockFix/BlockFix_BlockFixAPI.hxx | 2 +- src/BlockFix/BlockFix_CheckTool.cxx | 2 +- src/BlockFix/BlockFix_CheckTool.hxx | 2 +- .../BlockFix_PeriodicSurfaceModifier.cxx | 2 +- .../BlockFix_PeriodicSurfaceModifier.hxx | 2 +- src/BlockFix/BlockFix_SphereSpaceModifier.cxx | 2 +- src/BlockFix/BlockFix_SphereSpaceModifier.hxx | 2 +- src/BlockFix/BlockFix_UnionEdges.cxx | 2 +- src/BlockFix/BlockFix_UnionEdges.hxx | 2 +- src/BlockFix/BlockFix_UnionFaces.cxx | 2 +- src/BlockFix/BlockFix_UnionFaces.hxx | 2 +- src/BlockFix/CMakeLists.txt | 2 +- src/BlocksGUI/BlocksGUI.cxx | 2 +- src/BlocksGUI/BlocksGUI.h | 2 +- src/BlocksGUI/BlocksGUI_BlockDlg.cxx | 2 +- src/BlocksGUI/BlocksGUI_BlockDlg.h | 2 +- src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx | 2 +- src/BlocksGUI/BlocksGUI_ExplodeDlg.h | 2 +- src/BlocksGUI/BlocksGUI_PropagateDlg.cxx | 2 +- src/BlocksGUI/BlocksGUI_PropagateDlg.h | 2 +- src/BlocksGUI/BlocksGUI_QuadFaceDlg.cxx | 2 +- src/BlocksGUI/BlocksGUI_QuadFaceDlg.h | 2 +- src/BlocksGUI/BlocksGUI_TrsfDlg.cxx | 2 +- src/BlocksGUI/BlocksGUI_TrsfDlg.h | 2 +- src/BlocksGUI/CMakeLists.txt | 2 +- src/BooleanGUI/BooleanGUI.cxx | 2 +- src/BooleanGUI/BooleanGUI.h | 2 +- src/BooleanGUI/BooleanGUI_Dialog.cxx | 2 +- src/BooleanGUI/BooleanGUI_Dialog.h | 2 +- src/BooleanGUI/CMakeLists.txt | 2 +- src/BuildGUI/BuildGUI.cxx | 2 +- src/BuildGUI/BuildGUI.h | 2 +- src/BuildGUI/BuildGUI_CompoundDlg.cxx | 2 +- src/BuildGUI/BuildGUI_CompoundDlg.h | 2 +- src/BuildGUI/BuildGUI_EdgeDlg.cxx | 2 +- src/BuildGUI/BuildGUI_EdgeDlg.h | 2 +- src/BuildGUI/BuildGUI_FaceDlg.cxx | 2 +- src/BuildGUI/BuildGUI_FaceDlg.h | 2 +- src/BuildGUI/BuildGUI_ShellDlg.cxx | 2 +- src/BuildGUI/BuildGUI_ShellDlg.h | 2 +- src/BuildGUI/BuildGUI_SolidDlg.cxx | 2 +- src/BuildGUI/BuildGUI_SolidDlg.h | 2 +- src/BuildGUI/BuildGUI_WireDlg.cxx | 2 +- src/BuildGUI/BuildGUI_WireDlg.h | 2 +- src/BuildGUI/CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- src/CurveCreator/CMakeLists.txt | 2 +- src/CurveCreator/CurveCreator.hxx | 2 +- src/CurveCreator/CurveCreator_Curve.cxx | 2 +- src/CurveCreator/CurveCreator_Curve.hxx | 2 +- src/CurveCreator/CurveCreator_Diff.cxx | 2 +- src/CurveCreator/CurveCreator_Diff.hxx | 2 +- src/CurveCreator/CurveCreator_Displayer.cxx | 2 +- src/CurveCreator/CurveCreator_Displayer.hxx | 2 +- src/CurveCreator/CurveCreator_ICurve.hxx | 2 +- src/CurveCreator/CurveCreator_Macro.hxx | 2 +- .../CurveCreator_NewSectionDlg.cxx | 2 +- src/CurveCreator/CurveCreator_NewSectionDlg.h | 2 +- src/CurveCreator/CurveCreator_Operation.cxx | 2 +- src/CurveCreator/CurveCreator_Operation.hxx | 2 +- src/CurveCreator/CurveCreator_PosPoint.hxx | 2 +- src/CurveCreator/CurveCreator_Section.cxx | 2 +- src/CurveCreator/CurveCreator_Section.hxx | 2 +- src/CurveCreator/CurveCreator_TableView.cxx | 2 +- src/CurveCreator/CurveCreator_TableView.h | 2 +- src/CurveCreator/CurveCreator_TreeView.cxx | 2 +- src/CurveCreator/CurveCreator_TreeView.h | 2 +- src/CurveCreator/CurveCreator_Utils.cxx | 2 +- src/CurveCreator/CurveCreator_Utils.hxx | 2 +- src/CurveCreator/CurveCreator_UtilsICurve.cxx | 2 +- src/CurveCreator/CurveCreator_UtilsICurve.hxx | 2 +- src/CurveCreator/CurveCreator_Widget.cxx | 2 +- src/CurveCreator/CurveCreator_Widget.h | 2 +- src/DependencyTree/CMakeLists.txt | 2 +- src/DependencyTree/DependencyTree.h | 2 +- src/DependencyTree/DependencyTree_Arrow.cxx | 2 +- src/DependencyTree/DependencyTree_Arrow.h | 2 +- src/DependencyTree/DependencyTree_Object.cxx | 2 +- src/DependencyTree/DependencyTree_Object.h | 2 +- .../DependencyTree_Selector.cxx | 2 +- src/DependencyTree/DependencyTree_Selector.h | 2 +- src/DependencyTree/DependencyTree_View.cxx | 2 +- src/DependencyTree/DependencyTree_View.h | 2 +- .../DependencyTree_ViewModel.cxx | 2 +- src/DependencyTree/DependencyTree_ViewModel.h | 2 +- src/DisplayGUI/CMakeLists.txt | 2 +- src/DisplayGUI/DisplayGUI.cxx | 2 +- src/DisplayGUI/DisplayGUI.h | 2 +- src/DlgRef/CMakeLists.txt | 2 +- src/DlgRef/DlgRef.cxx | 2 +- src/DlgRef/DlgRef.h | 2 +- src/EntityGUI/CMakeLists.txt | 2 +- src/EntityGUI/EntityGUI.cxx | 2 +- src/EntityGUI/EntityGUI.h | 2 +- src/EntityGUI/EntityGUI_3DSketcherDlg.cxx | 2 +- src/EntityGUI/EntityGUI_3DSketcherDlg.h | 2 +- .../EntityGUI_FeatureDetectorDlg.cxx | 2 +- src/EntityGUI/EntityGUI_FeatureDetectorDlg.h | 2 +- src/EntityGUI/EntityGUI_FieldDlg.cxx | 2 +- src/EntityGUI/EntityGUI_FieldDlg.h | 2 +- src/EntityGUI/EntityGUI_IsolineDlg.cxx | 2 +- src/EntityGUI/EntityGUI_IsolineDlg.h | 2 +- src/EntityGUI/EntityGUI_PictureImportDlg.cxx | 2 +- src/EntityGUI/EntityGUI_PictureImportDlg.h | 2 +- src/EntityGUI/EntityGUI_PolylineDlg.cxx | 2 +- src/EntityGUI/EntityGUI_PolylineDlg.h | 2 +- src/EntityGUI/EntityGUI_SketcherDlg.cxx | 2 +- src/EntityGUI/EntityGUI_SketcherDlg.h | 2 +- src/EntityGUI/EntityGUI_SubShapeDlg.cxx | 2 +- src/EntityGUI/EntityGUI_SubShapeDlg.h | 2 +- src/EntityGUI/EntityGUI_SurfFromFaceDlg.cxx | 2 +- src/EntityGUI/EntityGUI_SurfFromFaceDlg.h | 2 +- src/EntityGUI/EntityGUI_Widgets.cxx | 2 +- src/EntityGUI/EntityGUI_Widgets.h | 2 +- src/GEOM/CMakeLists.txt | 2 +- src/GEOM/GEOM_Application.cxx | 2 +- src/GEOM/GEOM_Application.hxx | 2 +- src/GEOM/GEOM_BaseDriver.cxx | 2 +- src/GEOM/GEOM_BaseDriver.hxx | 2 +- src/GEOM/GEOM_BaseObject.cxx | 2 +- src/GEOM/GEOM_BaseObject.hxx | 2 +- .../GEOM_DataMapOfAsciiStringTransient.hxx | 2 +- src/GEOM/GEOM_Engine.cxx | 2 +- src/GEOM/GEOM_Engine.hxx | 2 +- src/GEOM/GEOM_Field.cxx | 2 +- src/GEOM/GEOM_Field.hxx | 2 +- src/GEOM/GEOM_Function.cxx | 2 +- src/GEOM/GEOM_Function.hxx | 2 +- src/GEOM/GEOM_IField.hxx | 2 +- src/GEOM/GEOM_IOperations.cxx | 2 +- src/GEOM/GEOM_IOperations.hxx | 2 +- src/GEOM/GEOM_ISubShape.hxx | 2 +- src/GEOM/GEOM_Object.cxx | 2 +- src/GEOM/GEOM_Object.hxx | 2 +- src/GEOM/GEOM_PythonDump.cxx | 2 +- src/GEOM/GEOM_PythonDump.hxx | 2 +- src/GEOM/GEOM_Solver.cxx | 2 +- src/GEOM/GEOM_Solver.hxx | 2 +- src/GEOM/GEOM_SubShapeDriver.cxx | 2 +- src/GEOM/GEOM_SubShapeDriver.hxx | 2 +- src/GEOMAlgo/CMakeLists.txt | 2 +- src/GEOMAlgo/GEOMAlgo.cdl | 2 +- src/GEOMAlgo/GEOMAlgo_Algo.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_Algo.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_AlgoTools.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_AlgoTools_1.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_BndSphere.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_BndSphere.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_BndSphere.lxx | 2 +- src/GEOMAlgo/GEOMAlgo_BndSphereTree.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_BndSphereTree.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_BoxBndTree.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_BoxBndTree.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_BuilderShape.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_BuilderShape.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_Clsf.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_Clsf.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_ClsfBox.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_ClsfBox.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_ClsfQuad.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_ClsfQuad.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_ClsfSolid.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_ClsfSolid.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_ClsfSurf.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_ClsfSurf.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_CoupleOfShapes.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_CoupleOfShapes.hxx | 2 +- ...taMapIteratorOfDataMapOfPassKeyInteger.hxx | 2 +- .../GEOMAlgo_DataMapOfPassKeyInteger.hxx | 2 +- .../GEOMAlgo_DataMapOfShapeMapOfShape.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_DataMapOfShapePnt.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_Extractor.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_Extractor.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_FinderShapeOn.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_FinderShapeOn.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_FinderShapeOn1.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_FinderShapeOn1.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_FinderShapeOn2.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_FinderShapeOn2.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_FinderShapeOnQuad.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_FinderShapeOnQuad.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_GetInPlace.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_GetInPlace.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_GetInPlace_1.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_GetInPlace_2.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_GetInPlace_3.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_GlueAnalyser.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_GlueAnalyser.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_GlueDetector.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_GlueDetector.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_Gluer.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_Gluer.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_Gluer2.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_Gluer2.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_Gluer2_1.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_Gluer2_2.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_Gluer2_3.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_GluerAlgo.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_GluerAlgo.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_HAlgo.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_HAlgo.hxx | 2 +- .../GEOMAlgo_IndexedDataMapOfIntegerShape.hxx | 2 +- ...ndexedDataMapOfPassKeyShapeListOfShape.hxx | 2 +- ...EOMAlgo_IndexedDataMapOfShapeBndSphere.hxx | 2 +- .../GEOMAlgo_IndexedDataMapOfShapeBox.hxx | 2 +- ...IndexedDataMapOfShapeIndexedMapOfShape.hxx | 2 +- ...EOMAlgo_IndexedDataMapOfShapeShapeInfo.hxx | 2 +- .../GEOMAlgo_IndexedDataMapOfShapeState.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_KindOfBounds.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_KindOfClosed.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_KindOfDef.hxx | 3 +- src/GEOMAlgo/GEOMAlgo_KindOfName.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_KindOfShape.hxx | 2 +- ...lgo_ListIteratorOfListOfCoupleOfShapes.hxx | 2 +- .../GEOMAlgo_ListIteratorOfListOfPnt.hxx | 2 +- .../GEOMAlgo_ListOfCoupleOfShapes.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_ListOfPnt.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_PassKey.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_PassKey.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_PassKeyMapHasher.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_PassKeyMapHasher.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_PassKeyShape.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_PassKeyShape.hxx | 2 +- .../GEOMAlgo_PassKeyShapeMapHasher.cxx | 2 +- .../GEOMAlgo_PassKeyShapeMapHasher.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_RemoverWebs.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_RemoverWebs.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShapeAlgo.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShapeAlgo.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShapeInfo.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShapeInfo.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShapeSolid.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShapeSolid.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShellSolid.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_ShellSolid.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_SolidSolid.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_SolidSolid.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_Splitter.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_Splitter.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_State.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_StateCollector.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_StateCollector.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_SurfaceTools.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_SurfaceTools.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_VertexSolid.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_VertexSolid.hxx | 2 +- src/GEOMAlgo/GEOMAlgo_WireSolid.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_WireSolid.hxx | 2 +- src/GEOMBase/CMakeLists.txt | 2 +- src/GEOMBase/GEOMBase.cxx | 2 +- src/GEOMBase/GEOMBase.h | 2 +- src/GEOMBase/GEOMBase_DlgSkeleton.cxx | 2 +- src/GEOMBase/GEOMBase_DlgSkeleton.h | 2 +- src/GEOMBase/GEOMBase_Helper.cxx | 2 +- src/GEOMBase/GEOMBase_Helper.h | 2 +- src/GEOMBase/GEOMBase_Skeleton.cxx | 2 +- src/GEOMBase/GEOMBase_Skeleton.h | 2 +- src/GEOMBase/GEOM_GEOMBase.hxx | 2 +- src/GEOMBase/GEOM_GenericObjPtr.cxx | 2 +- src/GEOMBase/GEOM_GenericObjPtr.h | 2 +- src/GEOMBase/GEOM_Operation.cxx | 2 +- src/GEOMBase/GEOM_Operation.h | 2 +- src/GEOMClient/CMakeLists.txt | 2 +- src/GEOMClient/GEOM_Client.cxx | 2 +- src/GEOMClient/GEOM_Client.hxx | 2 +- src/GEOMFiltersSelection/CMakeLists.txt | 2 +- .../GEOM_CompoundFilter.cxx | 2 +- .../GEOM_CompoundFilter.h | 2 +- src/GEOMFiltersSelection/GEOM_EdgeFilter.cxx | 2 +- src/GEOMFiltersSelection/GEOM_EdgeFilter.h | 2 +- src/GEOMFiltersSelection/GEOM_FaceFilter.cxx | 2 +- src/GEOMFiltersSelection/GEOM_FaceFilter.h | 2 +- .../GEOM_LogicalFilter.cxx | 2 +- src/GEOMFiltersSelection/GEOM_LogicalFilter.h | 2 +- src/GEOMFiltersSelection/GEOM_OCCFilter.cxx | 2 +- src/GEOMFiltersSelection/GEOM_OCCFilter.h | 2 +- .../GEOM_PreviewFilter.cxx | 2 +- src/GEOMFiltersSelection/GEOM_PreviewFilter.h | 2 +- .../GEOM_SelectionFilter.cxx | 2 +- .../GEOM_SelectionFilter.h | 2 +- src/GEOMFiltersSelection/GEOM_TypeFilter.cxx | 2 +- src/GEOMFiltersSelection/GEOM_TypeFilter.h | 2 +- src/GEOMGUI/CMakeLists.txt | 2 +- src/GEOMGUI/GEOMGUI.cxx | 2 +- src/GEOMGUI/GEOMGUI.h | 2 +- src/GEOMGUI/GEOMGUI_CreationInfoWdg.cxx | 2 +- src/GEOMGUI/GEOMGUI_CreationInfoWdg.h | 2 +- src/GEOMGUI/GEOMGUI_DimensionProperty.cxx | 2 +- src/GEOMGUI/GEOMGUI_DimensionProperty.h | 2 +- src/GEOMGUI/GEOMGUI_OCCSelector.cxx | 2 +- src/GEOMGUI/GEOMGUI_OCCSelector.h | 2 +- src/GEOMGUI/GEOMGUI_Selection.cxx | 2 +- src/GEOMGUI/GEOMGUI_Selection.h | 2 +- src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx | 2 +- src/GEOMGUI/GEOMGUI_TextTreeWdg.h | 2 +- src/GEOMGUI/GEOMPluginGUI.cxx | 2 +- src/GEOMGUI/GEOMPluginGUI.h | 2 +- src/GEOMGUI/GEOM_Displayer.cxx | 2 +- src/GEOMGUI/GEOM_Displayer.h | 2 +- src/GEOMGUI/GEOM_GEOMGUI.hxx | 2 +- src/GEOMGUI/GeometryGUI.cxx | 2 +- src/GEOMGUI/GeometryGUI.h | 2 +- src/GEOMGUI/GeometryGUI_Operations.h | 2 +- src/GEOMImpl/CMakeLists.txt | 2 +- src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_3DSketcherDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_ArcDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_ArcDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_ArchimedeDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_ArchimedeDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_Block6Explorer.cxx | 2 +- src/GEOMImpl/GEOMImpl_Block6Explorer.hxx | 2 +- src/GEOMImpl/GEOMImpl_BlockDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_BlockDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_BooleanDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_BooleanDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_BoxDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_BoxDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_ChamferDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_ChamferDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_CircleDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_CircleDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_ConeDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_ConeDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_CopyDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_CopyDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_CylinderDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_CylinderDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_DiskDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_DiskDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_EllipseDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_EllipseDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_ExportDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_ExportDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_FaceDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_FaceDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_FieldDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_FieldDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_Fillet1d.cxx | 2 +- src/GEOMImpl/GEOMImpl_Fillet1d.hxx | 2 +- src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_Fillet1dDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_Fillet2dDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_Fillet2dDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_FilletDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_FilletDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_FillingDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_FillingDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_Gen.cxx | 2 +- src/GEOMImpl/GEOMImpl_Gen.hxx | 2 +- src/GEOMImpl/GEOMImpl_GlueDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_GlueDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_HealingDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_HealingDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_I3DSketcher.hxx | 2 +- src/GEOMImpl/GEOMImpl_IArc.hxx | 2 +- src/GEOMImpl/GEOMImpl_IArchimede.hxx | 2 +- src/GEOMImpl/GEOMImpl_IBaseIEOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_IBaseIEOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_IBasicOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_IBasicOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_IBlockTrsf.hxx | 2 +- src/GEOMImpl/GEOMImpl_IBlocks.hxx | 2 +- src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_IBlocksOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_IBoolean.hxx | 2 +- src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_IBox.hxx | 2 +- src/GEOMImpl/GEOMImpl_IChamfer.hxx | 2 +- src/GEOMImpl/GEOMImpl_ICircle.hxx | 2 +- src/GEOMImpl/GEOMImpl_ICone.hxx | 2 +- src/GEOMImpl/GEOMImpl_ICopy.hxx | 2 +- src/GEOMImpl/GEOMImpl_ICurveParametric.hxx | 2 +- src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_ICylinder.hxx | 2 +- src/GEOMImpl/GEOMImpl_IDisk.hxx | 2 +- src/GEOMImpl/GEOMImpl_IECallBack.cxx | 2 +- src/GEOMImpl/GEOMImpl_IECallBack.hxx | 2 +- src/GEOMImpl/GEOMImpl_IEllipse.hxx | 2 +- src/GEOMImpl/GEOMImpl_IExtract.hxx | 2 +- src/GEOMImpl/GEOMImpl_IFace.hxx | 2 +- src/GEOMImpl/GEOMImpl_IFieldOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_IFieldOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_IFillet.hxx | 2 +- src/GEOMImpl/GEOMImpl_IFillet1d.hxx | 2 +- src/GEOMImpl/GEOMImpl_IFillet2d.hxx | 2 +- src/GEOMImpl/GEOMImpl_IFilling.hxx | 2 +- src/GEOMImpl/GEOMImpl_IGlue.hxx | 2 +- src/GEOMImpl/GEOMImpl_IGroupOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_IGroupOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_IHealing.hxx | 2 +- src/GEOMImpl/GEOMImpl_IHealingOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_IHealingOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_IImportExport.hxx | 2 +- src/GEOMImpl/GEOMImpl_IInsertOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_IInsertOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_IIsoline.hxx | 2 +- src/GEOMImpl/GEOMImpl_ILine.hxx | 2 +- src/GEOMImpl/GEOMImpl_ILocalOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_ILocalOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_IMarker.hxx | 2 +- src/GEOMImpl/GEOMImpl_IMeasure.hxx | 2 +- src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_IMirror.hxx | 2 +- src/GEOMImpl/GEOMImpl_IOffset.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPartition.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPipe.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPipeBiNormal.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPipeDiffSect.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPipePath.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPipeShellSect.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPlane.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPoint.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPolyline.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPolyline2D.cxx | 2 +- src/GEOMImpl/GEOMImpl_IPolyline2D.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPosition.hxx | 2 +- src/GEOMImpl/GEOMImpl_IPrism.hxx | 2 +- src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx | 2 +- src/GEOMImpl/GEOMImpl_IProjection.hxx | 2 +- src/GEOMImpl/GEOMImpl_IRevolution.hxx | 2 +- src/GEOMImpl/GEOMImpl_IRotate.hxx | 2 +- src/GEOMImpl/GEOMImpl_IScale.hxx | 2 +- src/GEOMImpl/GEOMImpl_IShapeExtend.hxx | 2 +- src/GEOMImpl/GEOMImpl_IShapes.hxx | 2 +- src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 2 +- src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_ISketcher.hxx | 2 +- src/GEOMImpl/GEOMImpl_ISphere.hxx | 2 +- src/GEOMImpl/GEOMImpl_ISpline.hxx | 2 +- src/GEOMImpl/GEOMImpl_IThruSections.hxx | 2 +- src/GEOMImpl/GEOMImpl_ITorus.hxx | 2 +- src/GEOMImpl/GEOMImpl_ITransferData.cxx | 2 +- src/GEOMImpl/GEOMImpl_ITransferData.hxx | 2 +- .../GEOMImpl_ITransformOperations.cxx | 2 +- .../GEOMImpl_ITransformOperations.hxx | 2 +- src/GEOMImpl/GEOMImpl_ITranslate.hxx | 2 +- src/GEOMImpl/GEOMImpl_IVector.hxx | 2 +- src/GEOMImpl/GEOMImpl_ImportDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_ImportDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_LineDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_LineDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_MarkerDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_MarkerDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_MeasureDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_MeasureDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_MirrorDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_MirrorDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_OffsetDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_OffsetDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_PartitionDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_PartitionDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_PipeDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_PipeDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_PipePathDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_PipePathDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_PlaneDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_PlaneDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_PointDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_PointDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_PolylineDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_PolylineDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_PolylineDumper.cxx | 2 +- src/GEOMImpl/GEOMImpl_PolylineDumper.hxx | 2 +- src/GEOMImpl/GEOMImpl_PositionDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_PositionDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_PrismDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_PrismDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_RevolutionDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_RevolutionDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_RotateDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_RotateDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_ScaleDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_ScaleDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_ShapeDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_ShapeDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_SketcherDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_SketcherDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_SphereDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_SphereDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_SplineDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_SplineDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_ThruSectionsDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_ThruSectionsDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_TorusDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_TorusDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_TranslateDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_TranslateDriver.hxx | 2 +- src/GEOMImpl/GEOMImpl_Types.hxx | 2 +- src/GEOMImpl/GEOMImpl_VectorDriver.cxx | 2 +- src/GEOMImpl/GEOMImpl_VectorDriver.hxx | 2 +- src/GEOMImpl/GEOM_GEOMImpl.hxx | 2 +- src/GEOMToolsGUI/CMakeLists.txt | 2 +- src/GEOMToolsGUI/GEOMToolsGUI.cxx | 2 +- src/GEOMToolsGUI/GEOMToolsGUI.h | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_1.cxx | 2 +- .../GEOMToolsGUI_DeflectionDlg.cxx | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_DeflectionDlg.h | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_DeleteDlg.cxx | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_DeleteDlg.h | 2 +- .../GEOMToolsGUI_LineWidthDlg.cxx | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_LineWidthDlg.h | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_MarkerDlg.cxx | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_MarkerDlg.h | 2 +- .../GEOMToolsGUI_MaterialPropertiesDlg.cxx | 2 +- .../GEOMToolsGUI_MaterialPropertiesDlg.h | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_NbIsosDlg.cxx | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_NbIsosDlg.h | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_PublishDlg.cxx | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_PublishDlg.h | 2 +- .../GEOMToolsGUI_ReduceStudyDlg.cxx | 2 +- .../GEOMToolsGUI_ReduceStudyDlg.h | 2 +- .../GEOMToolsGUI_TransparencyDlg.cxx | 2 +- .../GEOMToolsGUI_TransparencyDlg.h | 2 +- src/GEOMToolsGUI/GEOM_ToolsGUI.hxx | 2 +- src/GEOMUtils/CMakeLists.txt | 2 +- src/GEOMUtils/GEOMUtils.cxx | 2 +- src/GEOMUtils/GEOMUtils.hxx | 2 +- src/GEOMUtils/GEOMUtils_HTrsfCurve2d.cxx | 2 +- src/GEOMUtils/GEOMUtils_HTrsfCurve2d.hxx | 2 +- src/GEOMUtils/GEOMUtils_Hatcher.cxx | 2 +- src/GEOMUtils/GEOMUtils_Hatcher.hxx | 2 +- src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx | 2 +- src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx | 2 +- src/GEOMUtils/GEOMUtils_Trsf2d.cxx | 2 +- src/GEOMUtils/GEOMUtils_Trsf2d.hxx | 2 +- src/GEOMUtils/GEOMUtils_TrsfCurve2d.cxx | 2 +- src/GEOMUtils/GEOMUtils_TrsfCurve2d.hxx | 2 +- src/GEOMUtils/GEOMUtils_XmlHandler.cxx | 2 +- src/GEOMUtils/GEOMUtils_XmlHandler.hxx | 2 +- src/GEOM_I/CMakeLists.txt | 2 +- src/GEOM_I/GEOM_BaseObject_i.cc | 2 +- src/GEOM_I/GEOM_BaseObject_i.hh | 2 +- src/GEOM_I/GEOM_DumpPython.cc | 2 +- src/GEOM_I/GEOM_Field_i.cc | 2 +- src/GEOM_I/GEOM_Field_i.hh | 2 +- src/GEOM_I/GEOM_GEOM_I.hxx | 2 +- src/GEOM_I/GEOM_Gen_i.cc | 2 +- src/GEOM_I/GEOM_Gen_i.hh | 2 +- src/GEOM_I/GEOM_I3DPrimOperations_i.cc | 2 +- src/GEOM_I/GEOM_I3DPrimOperations_i.hh | 2 +- src/GEOM_I/GEOM_IBasicOperations_i.cc | 2 +- src/GEOM_I/GEOM_IBasicOperations_i.hh | 2 +- src/GEOM_I/GEOM_IBlocksOperations_i.cc | 2 +- src/GEOM_I/GEOM_IBlocksOperations_i.hh | 2 +- src/GEOM_I/GEOM_IBooleanOperations_i.cc | 2 +- src/GEOM_I/GEOM_IBooleanOperations_i.hh | 2 +- src/GEOM_I/GEOM_ICurvesOperations_i.cc | 2 +- src/GEOM_I/GEOM_ICurvesOperations_i.hh | 2 +- src/GEOM_I/GEOM_IFieldOperations_i.cc | 2 +- src/GEOM_I/GEOM_IFieldOperations_i.hh | 2 +- src/GEOM_I/GEOM_IGroupOperations_i.cc | 2 +- src/GEOM_I/GEOM_IGroupOperations_i.hh | 2 +- src/GEOM_I/GEOM_IHealingOperations_i.cc | 2 +- src/GEOM_I/GEOM_IHealingOperations_i.hh | 2 +- src/GEOM_I/GEOM_IInsertOperations_i.cc | 2 +- src/GEOM_I/GEOM_IInsertOperations_i.hh | 2 +- src/GEOM_I/GEOM_ILocalOperations_i.cc | 2 +- src/GEOM_I/GEOM_ILocalOperations_i.hh | 2 +- src/GEOM_I/GEOM_IMeasureOperations_i.cc | 2 +- src/GEOM_I/GEOM_IMeasureOperations_i.hh | 2 +- src/GEOM_I/GEOM_IOperations_i.cc | 2 +- src/GEOM_I/GEOM_IOperations_i.hh | 2 +- src/GEOM_I/GEOM_IShapesOperations_i.cc | 2 +- src/GEOM_I/GEOM_IShapesOperations_i.hh | 2 +- src/GEOM_I/GEOM_ITransformOperations_i.cc | 2 +- src/GEOM_I/GEOM_ITransformOperations_i.hh | 2 +- src/GEOM_I/GEOM_Object_i.cc | 2 +- src/GEOM_I/GEOM_Object_i.hh | 2 +- src/GEOM_I/GEOM_wrap.hxx | 2 +- src/GEOM_I_Superv/CMakeLists.txt | 2 +- src/GEOM_I_Superv/GEOM_I_Superv.hxx | 2 +- src/GEOM_I_Superv/GEOM_List_i.hh | 2 +- src/GEOM_I_Superv/GEOM_Superv_i.cc | 2 +- src/GEOM_I_Superv/GEOM_Superv_i.hh | 2 +- src/GEOM_PY/CMakeLists.txt | 2 +- src/GEOM_PY/__init__.py | 2 +- src/GEOM_PY/geomtools.py | 2 +- src/GEOM_PY/sketcher.py | 2 +- src/GEOM_PY/structelem/CMakeLists.txt | 2 +- src/GEOM_PY/structelem/__init__.py | 2 +- src/GEOM_PY/structelem/orientation.py | 2 +- src/GEOM_PY/structelem/parts.py | 2 +- src/GEOM_SWIG/AdvancedGEOMBuilder.py | 2 +- src/GEOM_SWIG/BREPPluginBuilder.py | 2 +- src/GEOM_SWIG/CMakeLists.txt | 2 +- src/GEOM_SWIG/GEOM_Nut.py | 2 +- src/GEOM_SWIG/GEOM_ObjectInfo.py | 2 +- src/GEOM_SWIG/GEOM_Partition1.py | 2 +- src/GEOM_SWIG/GEOM_Partition2.py | 2 +- src/GEOM_SWIG/GEOM_Partition3.py | 2 +- src/GEOM_SWIG/GEOM_Partition4.py | 2 +- src/GEOM_SWIG/GEOM_Partition5.py | 2 +- src/GEOM_SWIG/GEOM_Sketcher.py | 2 +- src/GEOM_SWIG/GEOM_Spanner.py | 2 +- src/GEOM_SWIG/GEOM_TestAll.py | 2 +- src/GEOM_SWIG/GEOM_TestField.py | 2 +- src/GEOM_SWIG/GEOM_TestHealing.py | 2 +- src/GEOM_SWIG/GEOM_TestMeasures.py | 2 +- src/GEOM_SWIG/GEOM_TestOthers.py | 2 +- src/GEOM_SWIG/GEOM_blocks.py | 2 +- src/GEOM_SWIG/GEOM_cyl2complementary.py | 2 +- src/GEOM_SWIG/GEOM_example.py | 2 +- src/GEOM_SWIG/GEOM_example2.py | 2 +- src/GEOM_SWIG/GEOM_example3.py | 2 +- src/GEOM_SWIG/GEOM_example4.py | 2 +- src/GEOM_SWIG/GEOM_example5.py | 2 +- src/GEOM_SWIG/GEOM_example6.py | 2 +- src/GEOM_SWIG/GEOM_example7.py | 2 +- src/GEOM_SWIG/GEOM_moteur.py | 2 +- src/GEOM_SWIG/GEOM_shared_modules.py | 2 +- src/GEOM_SWIG/GEOM_shellSolid.py | 2 +- src/GEOM_SWIG/GEOM_tube_geom.py | 2 +- src/GEOM_SWIG/GEOM_tube_geom_gg2.py | 2 +- src/GEOM_SWIG/GEOM_usinggeom.py | 2 +- src/GEOM_SWIG/IGESPluginBuilder.py | 2 +- src/GEOM_SWIG/PAL_MESH_019_020_geometry.py | 2 +- src/GEOM_SWIG/PAL_MESH_028_geometry.py | 2 +- src/GEOM_SWIG/PAL_MESH_030_geometry.py | 2 +- src/GEOM_SWIG/PAL_MESH_033_geometry.py | 2 +- src/GEOM_SWIG/PAL_MESH_035_geometry.py | 2 +- src/GEOM_SWIG/STEPPluginBuilder.py | 2 +- src/GEOM_SWIG/STLPluginBuilder.py | 2 +- src/GEOM_SWIG/VTKPluginBuilder.py | 2 +- src/GEOM_SWIG/XAOPluginBuilder.py | 2 +- src/GEOM_SWIG/__init__.py | 2 +- src/GEOM_SWIG/geomBuilder.py | 2 +- src/GEOM_SWIG/geompy.py | 2 +- src/GEOM_SWIG/gsketcher.py | 2 +- src/GEOM_SWIG_WITHIHM/CMakeLists.txt | 2 +- src/GEOM_SWIG_WITHIHM/libGEOM_Swig.cxx | 2 +- src/GEOM_SWIG_WITHIHM/libGEOM_Swig.h | 2 +- src/GEOM_SWIG_WITHIHM/libGEOM_Swig.i | 2 +- src/GenerationGUI/CMakeLists.txt | 2 +- src/GenerationGUI/GenerationGUI.cxx | 2 +- src/GenerationGUI/GenerationGUI.h | 2 +- .../GenerationGUI_FillingDlg.cxx | 2 +- src/GenerationGUI/GenerationGUI_FillingDlg.h | 2 +- src/GenerationGUI/GenerationGUI_PipeDlg.cxx | 2 +- src/GenerationGUI/GenerationGUI_PipeDlg.h | 2 +- .../GenerationGUI_PipePathDlg.cxx | 2 +- src/GenerationGUI/GenerationGUI_PipePathDlg.h | 2 +- src/GenerationGUI/GenerationGUI_PrismDlg.cxx | 2 +- src/GenerationGUI/GenerationGUI_PrismDlg.h | 2 +- src/GenerationGUI/GenerationGUI_RevolDlg.cxx | 2 +- src/GenerationGUI/GenerationGUI_RevolDlg.h | 2 +- .../GenerationGUI_ThicknessDlg.cxx | 2 +- .../GenerationGUI_ThicknessDlg.h | 2 +- src/GroupGUI/CMakeLists.txt | 2 +- src/GroupGUI/GroupGUI.cxx | 2 +- src/GroupGUI/GroupGUI.h | 2 +- src/GroupGUI/GroupGUI_BooleanDlg.cxx | 2 +- src/GroupGUI/GroupGUI_BooleanDlg.h | 2 +- src/GroupGUI/GroupGUI_GroupDlg.cxx | 2 +- src/GroupGUI/GroupGUI_GroupDlg.h | 2 +- src/IGESPlugin/CMakeLists.txt | 2 +- src/IGESPlugin/IGESPlugin_Engine.cxx | 2 +- src/IGESPlugin/IGESPlugin_Engine.hxx | 2 +- src/IGESPlugin/IGESPlugin_ExportDlg.cxx | 2 +- src/IGESPlugin/IGESPlugin_ExportDlg.h | 2 +- src/IGESPlugin/IGESPlugin_ExportDriver.cxx | 2 +- src/IGESPlugin/IGESPlugin_ExportDriver.hxx | 2 +- src/IGESPlugin/IGESPlugin_GUI.cxx | 2 +- src/IGESPlugin/IGESPlugin_GUI.h | 2 +- src/IGESPlugin/IGESPlugin_IECallBack.cxx | 2 +- src/IGESPlugin/IGESPlugin_IECallBack.hxx | 2 +- src/IGESPlugin/IGESPlugin_IExport.hxx | 2 +- src/IGESPlugin/IGESPlugin_IImport.hxx | 2 +- src/IGESPlugin/IGESPlugin_IOperations.cxx | 2 +- src/IGESPlugin/IGESPlugin_IOperations.hxx | 2 +- src/IGESPlugin/IGESPlugin_IOperations_i.cc | 2 +- src/IGESPlugin/IGESPlugin_IOperations_i.hh | 2 +- src/IGESPlugin/IGESPlugin_ImportDriver.cxx | 2 +- src/IGESPlugin/IGESPlugin_ImportDriver.hxx | 2 +- .../IGESPlugin_OperationsCreator.cxx | 2 +- .../IGESPlugin_OperationsCreator.hxx | 2 +- src/Material/CMakeLists.txt | 2 +- src/Material/Material.h | 2 +- src/Material/Material_Model.cxx | 2 +- src/Material/Material_Model.h | 2 +- src/Material/Material_ResourceMgr.cxx | 2 +- src/Material/Material_ResourceMgr.h | 2 +- src/Material/resources/SalomeMaterial.xml | 2 +- src/MeasureGUI/CMakeLists.txt | 2 +- src/MeasureGUI/MeasureGUI.cxx | 2 +- src/MeasureGUI/MeasureGUI.h | 2 +- src/MeasureGUI/MeasureGUI_AngleDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_AngleDlg.h | 2 +- src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_BndBoxDlg.h | 2 +- src/MeasureGUI/MeasureGUI_CenterMassDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_CenterMassDlg.h | 2 +- .../MeasureGUI_CheckCompoundOfBlocksDlg.cxx | 2 +- .../MeasureGUI_CheckCompoundOfBlocksDlg.h | 2 +- .../MeasureGUI_CheckSelfIntersectionsDlg.cxx | 2 +- .../MeasureGUI_CheckSelfIntersectionsDlg.h | 2 +- src/MeasureGUI/MeasureGUI_CheckShapeDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_CheckShapeDlg.h | 2 +- .../MeasureGUI_CreateDimensionDlg.cxx | 2 +- .../MeasureGUI_CreateDimensionDlg.h | 2 +- .../MeasureGUI_DimensionCreateTool.cxx | 2 +- .../MeasureGUI_DimensionCreateTool.h | 2 +- src/MeasureGUI/MeasureGUI_DimensionFilter.cxx | 2 +- src/MeasureGUI/MeasureGUI_DimensionFilter.h | 2 +- .../MeasureGUI_DimensionInteractor.cxx | 2 +- .../MeasureGUI_DimensionInteractor.h | 2 +- src/MeasureGUI/MeasureGUI_DistanceDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_DistanceDlg.h | 2 +- .../MeasureGUI_FastCheckIntersectionsDlg.cxx | 2 +- .../MeasureGUI_FastCheckIntersectionsDlg.h | 2 +- src/MeasureGUI/MeasureGUI_GetNonBlocksDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_GetNonBlocksDlg.h | 2 +- src/MeasureGUI/MeasureGUI_InertiaDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_InertiaDlg.h | 2 +- .../MeasureGUI_ManageDimensionsDlg.cxx | 2 +- .../MeasureGUI_ManageDimensionsDlg.h | 2 +- src/MeasureGUI/MeasureGUI_MaxToleranceDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_MaxToleranceDlg.h | 2 +- src/MeasureGUI/MeasureGUI_NormaleDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_NormaleDlg.h | 2 +- src/MeasureGUI/MeasureGUI_PointDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_PointDlg.h | 2 +- src/MeasureGUI/MeasureGUI_PropertiesDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_PropertiesDlg.h | 2 +- .../MeasureGUI_ShapeStatisticsDlg.cxx | 2 +- .../MeasureGUI_ShapeStatisticsDlg.h | 2 +- src/MeasureGUI/MeasureGUI_Skeleton.cxx | 2 +- src/MeasureGUI/MeasureGUI_Skeleton.h | 2 +- src/MeasureGUI/MeasureGUI_WhatisDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_WhatisDlg.h | 2 +- src/MeasureGUI/MeasureGUI_Widgets.cxx | 2 +- src/MeasureGUI/MeasureGUI_Widgets.h | 2 +- src/MeasureGUI/MeasureGUI_definitions.h | 2 +- src/OBJECT/CMakeLists.txt | 2 +- src/OBJECT/GEOM_AISDimension.cxx | 2 +- src/OBJECT/GEOM_AISDimension.hxx | 2 +- src/OBJECT/GEOM_AISShape.cxx | 2 +- src/OBJECT/GEOM_AISShape.hxx | 2 +- src/OBJECT/GEOM_AISTrihedron.cxx | 2 +- src/OBJECT/GEOM_AISTrihedron.hxx | 2 +- src/OBJECT/GEOM_AISVector.cxx | 2 +- src/OBJECT/GEOM_AISVector.hxx | 2 +- src/OBJECT/GEOM_Actor.cxx | 2 +- src/OBJECT/GEOM_Actor.h | 2 +- src/OBJECT/GEOM_Constants.cxx | 2 +- src/OBJECT/GEOM_Constants.h | 2 +- src/OBJECT/GEOM_DeviceActor.cxx | 2 +- src/OBJECT/GEOM_DeviceActor.h | 2 +- src/OBJECT/GEOM_InteractiveObject.cxx | 2 +- src/OBJECT/GEOM_InteractiveObject.hxx | 2 +- src/OBJECT/GEOM_OBJECT_defs.hxx | 2 +- src/OBJECT/GEOM_OCCReader.cxx | 2 +- src/OBJECT/GEOM_OCCReader.h | 2 +- src/OBJECT/GEOM_PainterPolyDataMapper.cxx | 2 +- src/OBJECT/GEOM_PainterPolyDataMapper.h | 2 +- src/OBJECT/GEOM_SmartPtr.h | 2 +- src/OBJECT/GEOM_TopWireframeShape.cxx | 2 +- src/OBJECT/GEOM_TopWireframeShape.hxx | 2 +- src/OBJECT/GEOM_VTKPropertyMaterial.cxx | 2 +- src/OBJECT/GEOM_VTKPropertyMaterial.hxx | 2 +- src/OBJECT/GEOM_VTKTrihedron.cxx | 2 +- src/OBJECT/GEOM_VTKTrihedron.hxx | 2 +- src/OCC2VTK/CMakeLists.txt | 2 +- src/OCC2VTK/GEOM_EdgeSource.cxx | 2 +- src/OCC2VTK/GEOM_EdgeSource.h | 2 +- src/OCC2VTK/GEOM_FaceSource.cxx | 2 +- src/OCC2VTK/GEOM_FaceSource.h | 2 +- src/OCC2VTK/GEOM_ShadingFace.cxx | 2 +- src/OCC2VTK/GEOM_ShadingFace.h | 2 +- src/OCC2VTK/GEOM_VertexSource.cxx | 2 +- src/OCC2VTK/GEOM_VertexSource.h | 2 +- src/OCC2VTK/GEOM_WireframeFace.cxx | 2 +- src/OCC2VTK/GEOM_WireframeFace.h | 2 +- src/OCC2VTK/OCC2VTK.h | 2 +- src/OCC2VTK/OCC2VTK_Tools.cxx | 2 +- src/OCC2VTK/OCC2VTK_Tools.h | 2 +- src/OperationGUI/CMakeLists.txt | 2 +- src/OperationGUI/OperationGUI.cxx | 2 +- src/OperationGUI/OperationGUI.h | 2 +- .../OperationGUI_ArchimedeDlg.cxx | 2 +- src/OperationGUI/OperationGUI_ArchimedeDlg.h | 2 +- src/OperationGUI/OperationGUI_ChamferDlg.cxx | 2 +- src/OperationGUI/OperationGUI_ChamferDlg.h | 2 +- src/OperationGUI/OperationGUI_ClippingDlg.cxx | 2 +- src/OperationGUI/OperationGUI_ClippingDlg.h | 2 +- .../OperationGUI_ExtractionDlg.cxx | 2 +- src/OperationGUI/OperationGUI_ExtractionDlg.h | 2 +- .../OperationGUI_ExtrudedFeatureDlg.cxx | 2 +- .../OperationGUI_ExtrudedFeatureDlg.h | 2 +- .../OperationGUI_Fillet1d2dDlg.cxx | 2 +- src/OperationGUI/OperationGUI_Fillet1d2dDlg.h | 2 +- src/OperationGUI/OperationGUI_FilletDlg.cxx | 2 +- src/OperationGUI/OperationGUI_FilletDlg.h | 2 +- .../OperationGUI_GetShapesOnShapeDlg.cxx | 2 +- .../OperationGUI_GetShapesOnShapeDlg.h | 2 +- .../OperationGUI_GetSharedShapesDlg.cxx | 2 +- .../OperationGUI_GetSharedShapesDlg.h | 2 +- src/OperationGUI/OperationGUI_MaterialDlg.cxx | 2 +- src/OperationGUI/OperationGUI_MaterialDlg.h | 2 +- .../OperationGUI_PartitionDlg.cxx | 2 +- src/OperationGUI/OperationGUI_PartitionDlg.h | 2 +- .../OperationGUI_TransferDataDlg.cxx | 2 +- .../OperationGUI_TransferDataDlg.h | 2 +- src/PrimitiveGUI/CMakeLists.txt | 2 +- src/PrimitiveGUI/PrimitiveGUI.cxx | 2 +- src/PrimitiveGUI/PrimitiveGUI.h | 2 +- src/PrimitiveGUI/PrimitiveGUI_BoxDlg.cxx | 2 +- src/PrimitiveGUI/PrimitiveGUI_BoxDlg.h | 2 +- src/PrimitiveGUI/PrimitiveGUI_ConeDlg.cxx | 2 +- src/PrimitiveGUI/PrimitiveGUI_ConeDlg.h | 2 +- src/PrimitiveGUI/PrimitiveGUI_CylinderDlg.cxx | 2 +- src/PrimitiveGUI/PrimitiveGUI_CylinderDlg.h | 2 +- src/PrimitiveGUI/PrimitiveGUI_DiskDlg.cxx | 2 +- src/PrimitiveGUI/PrimitiveGUI_DiskDlg.h | 2 +- src/PrimitiveGUI/PrimitiveGUI_FaceDlg.cxx | 2 +- src/PrimitiveGUI/PrimitiveGUI_FaceDlg.h | 2 +- src/PrimitiveGUI/PrimitiveGUI_SphereDlg.cxx | 2 +- src/PrimitiveGUI/PrimitiveGUI_SphereDlg.h | 2 +- src/PrimitiveGUI/PrimitiveGUI_TorusDlg.cxx | 2 +- src/PrimitiveGUI/PrimitiveGUI_TorusDlg.h | 2 +- src/RepairGUI/CMakeLists.txt | 2 +- src/RepairGUI/RepairGUI.cxx | 2 +- src/RepairGUI/RepairGUI.h | 2 +- .../RepairGUI_ChangeOrientationDlg.cxx | 2 +- .../RepairGUI_ChangeOrientationDlg.h | 2 +- src/RepairGUI/RepairGUI_CloseContourDlg.cxx | 2 +- src/RepairGUI/RepairGUI_CloseContourDlg.h | 2 +- src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx | 2 +- src/RepairGUI/RepairGUI_DivideEdgeDlg.h | 2 +- src/RepairGUI/RepairGUI_FreeBoundDlg.cxx | 2 +- src/RepairGUI/RepairGUI_FreeBoundDlg.h | 2 +- src/RepairGUI/RepairGUI_FreeFacesDlg.cxx | 2 +- src/RepairGUI/RepairGUI_FreeFacesDlg.h | 2 +- src/RepairGUI/RepairGUI_FuseEdgesDlg.cxx | 2 +- src/RepairGUI/RepairGUI_FuseEdgesDlg.h | 2 +- src/RepairGUI/RepairGUI_GlueDlg.cxx | 2 +- src/RepairGUI/RepairGUI_GlueDlg.h | 2 +- src/RepairGUI/RepairGUI_InspectObjectDlg.cxx | 2 +- src/RepairGUI/RepairGUI_InspectObjectDlg.h | 2 +- src/RepairGUI/RepairGUI_LimitToleranceDlg.cxx | 2 +- src/RepairGUI/RepairGUI_LimitToleranceDlg.h | 2 +- .../RepairGUI_RemoveExtraEdgesDlg.cxx | 2 +- src/RepairGUI/RepairGUI_RemoveExtraEdgesDlg.h | 2 +- src/RepairGUI/RepairGUI_RemoveHolesDlg.cxx | 2 +- src/RepairGUI/RepairGUI_RemoveHolesDlg.h | 2 +- src/RepairGUI/RepairGUI_RemoveIntWiresDlg.cxx | 2 +- src/RepairGUI/RepairGUI_RemoveIntWiresDlg.h | 2 +- src/RepairGUI/RepairGUI_RemoveWebsDlg.cxx | 2 +- src/RepairGUI/RepairGUI_RemoveWebsDlg.h | 2 +- src/RepairGUI/RepairGUI_SewingDlg.cxx | 2 +- src/RepairGUI/RepairGUI_SewingDlg.h | 2 +- src/RepairGUI/RepairGUI_ShapeProcessDlg.cxx | 2 +- src/RepairGUI/RepairGUI_ShapeProcessDlg.h | 2 +- src/RepairGUI/RepairGUI_SuppressFacesDlg.cxx | 2 +- src/RepairGUI/RepairGUI_SuppressFacesDlg.h | 2 +- src/RepairGUI/RepairGUI_UnionFacesDlg.cxx | 2 +- src/RepairGUI/RepairGUI_UnionFacesDlg.h | 2 +- src/SKETCHER/CMakeLists.txt | 2 +- src/SKETCHER/Sketcher.hxx | 2 +- src/SKETCHER/Sketcher_Profile.cxx | 2 +- src/SKETCHER/Sketcher_Profile.hxx | 2 +- src/SKETCHER/Sketcher_Utils.cxx | 2 +- src/SKETCHER/Sketcher_Utils.hxx | 2 +- src/STEPPlugin/CMakeLists.txt | 2 +- src/STEPPlugin/STEPPlugin_Engine.cxx | 2 +- src/STEPPlugin/STEPPlugin_Engine.hxx | 2 +- src/STEPPlugin/STEPPlugin_ExportDlg.cxx | 2 +- src/STEPPlugin/STEPPlugin_ExportDlg.h | 2 +- src/STEPPlugin/STEPPlugin_ExportDriver.cxx | 2 +- src/STEPPlugin/STEPPlugin_ExportDriver.hxx | 2 +- src/STEPPlugin/STEPPlugin_GUI.cxx | 2 +- src/STEPPlugin/STEPPlugin_GUI.h | 2 +- src/STEPPlugin/STEPPlugin_IECallBack.cxx | 2 +- src/STEPPlugin/STEPPlugin_IECallBack.hxx | 2 +- src/STEPPlugin/STEPPlugin_IExport.hxx | 2 +- src/STEPPlugin/STEPPlugin_IImport.hxx | 2 +- src/STEPPlugin/STEPPlugin_IOperations.cxx | 2 +- src/STEPPlugin/STEPPlugin_IOperations.hxx | 2 +- src/STEPPlugin/STEPPlugin_IOperations_i.cc | 2 +- src/STEPPlugin/STEPPlugin_IOperations_i.hh | 2 +- src/STEPPlugin/STEPPlugin_ImportDlg.cxx | 2 +- src/STEPPlugin/STEPPlugin_ImportDlg.h | 2 +- src/STEPPlugin/STEPPlugin_ImportDriver.cxx | 2 +- src/STEPPlugin/STEPPlugin_ImportDriver.hxx | 2 +- .../STEPPlugin_OperationsCreator.cxx | 2 +- .../STEPPlugin_OperationsCreator.hxx | 2 +- src/STLPlugin/CMakeLists.txt | 2 +- src/STLPlugin/STLPlugin_Engine.cxx | 2 +- src/STLPlugin/STLPlugin_Engine.hxx | 2 +- src/STLPlugin/STLPlugin_ExportDlg.cxx | 2 +- src/STLPlugin/STLPlugin_ExportDlg.h | 2 +- src/STLPlugin/STLPlugin_ExportDriver.cxx | 2 +- src/STLPlugin/STLPlugin_ExportDriver.hxx | 2 +- src/STLPlugin/STLPlugin_GUI.cxx | 2 +- src/STLPlugin/STLPlugin_GUI.h | 2 +- src/STLPlugin/STLPlugin_IECallBack.cxx | 2 +- src/STLPlugin/STLPlugin_IECallBack.hxx | 2 +- src/STLPlugin/STLPlugin_IExport.hxx | 2 +- src/STLPlugin/STLPlugin_IImport.hxx | 2 +- src/STLPlugin/STLPlugin_IOperations.cxx | 2 +- src/STLPlugin/STLPlugin_IOperations.hxx | 2 +- src/STLPlugin/STLPlugin_IOperations_i.cc | 2 +- src/STLPlugin/STLPlugin_IOperations_i.hh | 2 +- src/STLPlugin/STLPlugin_ImportDriver.cxx | 2 +- src/STLPlugin/STLPlugin_ImportDriver.hxx | 2 +- src/STLPlugin/STLPlugin_OperationsCreator.cxx | 2 +- src/STLPlugin/STLPlugin_OperationsCreator.hxx | 2 +- src/ShHealOper/CMakeLists.txt | 2 +- .../ShHealOper_ChangeOrientation.cxx | 2 +- .../ShHealOper_ChangeOrientation.hxx | 2 +- src/ShHealOper/ShHealOper_CloseContour.cxx | 2 +- src/ShHealOper/ShHealOper_CloseContour.hxx | 2 +- src/ShHealOper/ShHealOper_EdgeDivide.cxx | 2 +- src/ShHealOper/ShHealOper_EdgeDivide.hxx | 2 +- src/ShHealOper/ShHealOper_FillHoles.cxx | 2 +- src/ShHealOper/ShHealOper_FillHoles.hxx | 2 +- src/ShHealOper/ShHealOper_ModifStats.hxx | 2 +- src/ShHealOper/ShHealOper_RemoveFace.cxx | 2 +- src/ShHealOper/ShHealOper_RemoveFace.hxx | 2 +- .../ShHealOper_RemoveInternalWires.cxx | 2 +- .../ShHealOper_RemoveInternalWires.hxx | 2 +- src/ShHealOper/ShHealOper_Sewing.cxx | 2 +- src/ShHealOper/ShHealOper_Sewing.hxx | 2 +- src/ShHealOper/ShHealOper_ShapeProcess.cxx | 2 +- src/ShHealOper/ShHealOper_ShapeProcess.hxx | 2 +- src/ShHealOper/ShHealOper_SpiltCurve2d.hxx | 2 +- src/ShHealOper/ShHealOper_SplitCurve2d.cxx | 2 +- src/ShHealOper/ShHealOper_SplitCurve2d.hxx | 2 +- src/ShHealOper/ShHealOper_SplitCurve3d.cxx | 2 +- src/ShHealOper/ShHealOper_SplitCurve3d.hxx | 2 +- src/ShHealOper/ShHealOper_Tool.cxx | 2 +- src/ShHealOper/ShHealOper_Tool.hxx | 2 +- src/ShapeRecognition/CMakeLists.txt | 2 +- .../ShapeRec_FeatureDetector.cxx | 2 +- .../ShapeRec_FeatureDetector.hxx | 2 +- src/Tools/CMakeLists.txt | 2 +- src/Tools/geom_plugins.py | 2 +- src/Tools/t_shape/CMakeLists.txt | 3 +- src/Tools/t_shape/__init__.py | 18 + src/Tools/t_shape/t_shape_builder.py | 18 + src/Tools/t_shape/t_shape_dialog.py | 4 +- src/Tools/t_shape/t_shape_progress.py | 2 +- src/TransformationGUI/CMakeLists.txt | 2 +- src/TransformationGUI/TransformationGUI.cxx | 2 +- src/TransformationGUI/TransformationGUI.h | 2 +- .../TransformationGUI_ExtensionDlg.cxx | 2 +- .../TransformationGUI_ExtensionDlg.h | 2 +- .../TransformationGUI_MirrorDlg.cxx | 2 +- .../TransformationGUI_MirrorDlg.h | 2 +- .../TransformationGUI_MultiRotationDlg.cxx | 2 +- .../TransformationGUI_MultiRotationDlg.h | 2 +- .../TransformationGUI_MultiTranslationDlg.cxx | 2 +- .../TransformationGUI_MultiTranslationDlg.h | 2 +- .../TransformationGUI_OffsetDlg.cxx | 2 +- .../TransformationGUI_OffsetDlg.h | 2 +- .../TransformationGUI_PositionDlg.cxx | 2 +- .../TransformationGUI_PositionDlg.h | 2 +- .../TransformationGUI_ProjectionDlg.cxx | 2 +- .../TransformationGUI_ProjectionDlg.h | 2 +- .../TransformationGUI_ProjectionOnCylDlg.cxx | 2 +- .../TransformationGUI_ProjectionOnCylDlg.h | 2 +- .../TransformationGUI_RotationDlg.cxx | 2 +- .../TransformationGUI_RotationDlg.h | 2 +- .../TransformationGUI_ScaleDlg.cxx | 2 +- .../TransformationGUI_ScaleDlg.h | 2 +- .../TransformationGUI_TranslationDlg.cxx | 2 +- .../TransformationGUI_TranslationDlg.h | 2 +- src/VTKPlugin/CMakeLists.txt | 2 +- src/VTKPlugin/VTKPlugin_Engine.cxx | 2 +- src/VTKPlugin/VTKPlugin_Engine.hxx | 2 +- src/VTKPlugin/VTKPlugin_ExportDlg.cxx | 2 +- src/VTKPlugin/VTKPlugin_ExportDlg.h | 2 +- src/VTKPlugin/VTKPlugin_ExportDriver.cxx | 2 +- src/VTKPlugin/VTKPlugin_ExportDriver.hxx | 2 +- src/VTKPlugin/VTKPlugin_GUI.cxx | 2 +- src/VTKPlugin/VTKPlugin_GUI.h | 2 +- src/VTKPlugin/VTKPlugin_IECallBack.cxx | 2 +- src/VTKPlugin/VTKPlugin_IECallBack.hxx | 2 +- src/VTKPlugin/VTKPlugin_IExport.hxx | 2 +- src/VTKPlugin/VTKPlugin_IOperations.cxx | 2 +- src/VTKPlugin/VTKPlugin_IOperations.hxx | 2 +- src/VTKPlugin/VTKPlugin_IOperations_i.cc | 2 +- src/VTKPlugin/VTKPlugin_IOperations_i.hh | 2 +- src/VTKPlugin/VTKPlugin_OperationsCreator.cxx | 2 +- src/VTKPlugin/VTKPlugin_OperationsCreator.hxx | 2 +- src/XAO/CMakeLists.txt | 2 +- src/XAO/XAO.hxx | 2 +- src/XAO/XAO_BooleanField.cxx | 2 +- src/XAO/XAO_BooleanField.hxx | 2 +- src/XAO/XAO_BooleanStep.cxx | 2 +- src/XAO/XAO_BooleanStep.hxx | 2 +- src/XAO/XAO_BrepGeometry.cxx | 2 +- src/XAO/XAO_BrepGeometry.hxx | 2 +- src/XAO/XAO_DoubleField.cxx | 2 +- src/XAO/XAO_DoubleField.hxx | 2 +- src/XAO/XAO_DoubleStep.cxx | 2 +- src/XAO/XAO_DoubleStep.hxx | 2 +- src/XAO/XAO_Exception.hxx | 2 +- src/XAO/XAO_Field.cxx | 2 +- src/XAO/XAO_Field.hxx | 2 +- src/XAO/XAO_GeometricElement.cxx | 2 +- src/XAO/XAO_GeometricElement.hxx | 2 +- src/XAO/XAO_Geometry.cxx | 2 +- src/XAO/XAO_Geometry.hxx | 2 +- src/XAO/XAO_Group.cxx | 2 +- src/XAO/XAO_Group.hxx | 2 +- src/XAO/XAO_IntegerField.cxx | 2 +- src/XAO/XAO_IntegerField.hxx | 2 +- src/XAO/XAO_IntegerStep.cxx | 2 +- src/XAO/XAO_IntegerStep.hxx | 2 +- src/XAO/XAO_Step.cxx | 2 +- src/XAO/XAO_Step.hxx | 2 +- src/XAO/XAO_StringField.cxx | 2 +- src/XAO/XAO_StringField.hxx | 2 +- src/XAO/XAO_StringStep.cxx | 2 +- src/XAO/XAO_StringStep.hxx | 2 +- src/XAO/XAO_Xao.cxx | 2 +- src/XAO/XAO_Xao.hxx | 2 +- src/XAO/XAO_XaoExporter.cxx | 2 +- src/XAO/XAO_XaoExporter.hxx | 2 +- src/XAO/XAO_XaoUtils.cxx | 2 +- src/XAO/XAO_XaoUtils.hxx | 2 +- src/XAO/tests/BrepGeometryTest.cxx | 2 +- src/XAO/tests/BrepGeometryTest.hxx | 2 +- src/XAO/tests/CMakeLists.txt | 2 +- src/XAO/tests/FieldTest.cxx | 2 +- src/XAO/tests/FieldTest.hxx | 2 +- src/XAO/tests/GeometryTest.cxx | 2 +- src/XAO/tests/GeometryTest.hxx | 2 +- src/XAO/tests/GroupTest.cxx | 2 +- src/XAO/tests/GroupTest.hxx | 2 +- src/XAO/tests/ImportExportTest.cxx | 2 +- src/XAO/tests/ImportExportTest.hxx | 2 +- src/XAO/tests/MainTest.hxx | 2 +- src/XAO/tests/TestUtils.hxx | 2 +- src/XAO/tests/XAOTests.cxx | 2 +- src/XAO/tests/XaoTest.cxx | 2 +- src/XAO/tests/XaoTest.hxx | 2 +- src/XAO/tests/XaoUtilsTest.cxx | 2 +- src/XAO/tests/XaoUtilsTest.hxx | 2 +- src/XAO/tests/coverage_report.sh | 2 +- src/XAOPlugin/CMakeLists.txt | 2 +- src/XAOPlugin/XAOPlugin_Driver.cxx | 2 +- src/XAOPlugin/XAOPlugin_Driver.hxx | 2 +- src/XAOPlugin/XAOPlugin_Engine.cxx | 2 +- src/XAOPlugin/XAOPlugin_Engine.hxx | 2 +- src/XAOPlugin/XAOPlugin_ExportDlg.cxx | 2 +- src/XAOPlugin/XAOPlugin_ExportDlg.h | 2 +- src/XAOPlugin/XAOPlugin_GUI.cxx | 2 +- src/XAOPlugin/XAOPlugin_GUI.h | 2 +- src/XAOPlugin/XAOPlugin_IECallBack.cxx | 2 +- src/XAOPlugin/XAOPlugin_IECallBack.hxx | 2 +- src/XAOPlugin/XAOPlugin_IImportExport.hxx | 2 +- src/XAOPlugin/XAOPlugin_IOperations.cxx | 2 +- src/XAOPlugin/XAOPlugin_IOperations.hxx | 2 +- src/XAOPlugin/XAOPlugin_IOperations_i.cc | 2 +- src/XAOPlugin/XAOPlugin_IOperations_i.hh | 2 +- src/XAOPlugin/XAOPlugin_ImportDlg.cxx | 2 +- src/XAOPlugin/XAOPlugin_ImportDlg.h | 2 +- src/XAOPlugin/XAOPlugin_OperationsCreator.cxx | 2 +- src/XAOPlugin/XAOPlugin_OperationsCreator.hxx | 2 +- src/XAO_Swig/CMakeLists.txt | 2 +- src/XAO_Swig/xao.i | 19 + 1215 files changed, 1375 insertions(+), 1713 deletions(-) delete mode 100644 AUTHORS delete mode 100644 ChangeLog delete mode 100644 INSTALL delete mode 100644 LICENCE delete mode 100644 NEWS diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index e69de29bb..000000000 diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d4a1a570..c191f1f37 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2013-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index e69de29bb..000000000 diff --git a/GEOM_version.h.in b/GEOM_version.h.in index 0775f1724..f901288be 100644 --- a/GEOM_version.h.in +++ b/GEOM_version.h.in @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 71869d64e..000000000 --- a/INSTALL +++ /dev/null @@ -1 +0,0 @@ -SALOME2 : GEOM module diff --git a/LICENCE b/LICENCE deleted file mode 100644 index b1e3f5a26..000000000 --- a/LICENCE +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/NEWS b/NEWS deleted file mode 100644 index e69de29bb..000000000 diff --git a/README b/README index e69de29bb..5d316403c 100644 --- a/README +++ b/README @@ -0,0 +1,112 @@ +********************* +About SALOME Geometry +********************* + +SALOME Geometry module implements the CAD modeling services: +- Import and export of geometrical models in IGES, BREP, STEP, STL, XAO and VTK formats; +- Construct geometrical objects using a wide range of functions; +- Display geometrical objects in the 3D viewer; +- Transform geometrical objects using various algorithms; +- Repair geometrical objects (shape healing); +- View information about geometrical objects using measurement tools; +- Design shapes from pictures. + +For more information please visit the SALOME platform web site: + + + +======= +License +======= + +SALOME platform is distributed under the GNU Lesser General Public License. +See COPYING file for more details. + +Also, additional information can be found at SALOME platform web site: + + + +============ +Installation +============ + +-------------- +Pre-requisites +-------------- + +SALOME platform relies on a set of third-party softwares; some of them are needed +at build time only, while other ones are needed in runtime also. + +For more information about the pre-requisites please visit SALOME platform web +site: + +* Check Release Notes and Software Requirements of the latest SALOME release at + + + +* Pre-requisites page at SALOME web site: + + + +Note: SALOME Geometry module needs SALOME KERNEL and SALOME GUI as +pre-requisites. + +------------------ +Basic Installation +------------------ + +The build procedure of the SALOME platform is implemented with CMake. +In order to build the module you have to do the following actions: + +1. Set up environment for pre-requisites (see "Pre-requisites" section above). + +2. Create a build directory: + + % mkdir GEOM_BUILD + +3. Configure the build procedure: + + % cd GEOM_BUILD + % cmake -DCMAKE_BUILD_TYPE= -DCMAKE_INSTALL_PREFIX= + + where + - is either Release or Debug (default: Release); + - is a destination folder to install SALOME Geometry + module (default: /usr); + - is a path to the SALOME Geometry sources directory. + + Note: by default (if CMAKE_INSTALL_PREFIX option is not given), SALOME Geometry + module will be configured for installation to the /usr directory that requires + root permissions to complete the installation. + +4. Build and install: + + % make + % make install + + This will install SALOME Geometry module to the + specified to cmake command on the previous step. + +------------------- +Custom installation +------------------- + +SALOME Geometry module supports a set of advanced configuration options; +for more details learn CMakeLists.txt file in the root source directory. + +You can also use other options of cmake command to customize your installation. +Learn more about available options by typing + + % cmake --help + +============= +Documentation +============= + +The directory doc contains additional documentation file of SALOME Geomtry module. + +=============== +Troubleshooting +=============== + +Please, send a mail to webmaster.salome@opencascade.com. diff --git a/SalomeGEOMConfig.cmake.in b/SalomeGEOMConfig.cmake.in index 42db6d36b..72c770337 100644 --- a/SalomeGEOMConfig.cmake.in +++ b/SalomeGEOMConfig.cmake.in @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2013-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/adm_local/CMakeLists.txt b/adm_local/CMakeLists.txt index 3f181513f..4150922ef 100755 --- a/adm_local/CMakeLists.txt +++ b/adm_local/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/adm_local/cmake_files/CMakeLists.txt b/adm_local/cmake_files/CMakeLists.txt index b8361c0fc..05aea8be8 100755 --- a/adm_local/cmake_files/CMakeLists.txt +++ b/adm_local/cmake_files/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2012-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/adm_local/cmake_files/FindGEOM.cmake b/adm_local/cmake_files/FindGEOM.cmake index 2f42ba9c9..e9cf725e1 100644 --- a/adm_local/cmake_files/FindGEOM.cmake +++ b/adm_local/cmake_files/FindGEOM.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/adm_local/cmake_files/FindSalomeGEOM.cmake b/adm_local/cmake_files/FindSalomeGEOM.cmake index bccfc2328..309df0f35 100644 --- a/adm_local/cmake_files/FindSalomeGEOM.cmake +++ b/adm_local/cmake_files/FindSalomeGEOM.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/adm_local/cmake_files/FindSalomeOpenCV.cmake b/adm_local/cmake_files/FindSalomeOpenCV.cmake index 63932fea4..bcab5e7ae 100644 --- a/adm_local/cmake_files/FindSalomeOpenCV.cmake +++ b/adm_local/cmake_files/FindSalomeOpenCV.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2013-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/adm_local/unix/CMakeLists.txt b/adm_local/unix/CMakeLists.txt index 0e7521931..b27faef5b 100755 --- a/adm_local/unix/CMakeLists.txt +++ b/adm_local/unix/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2012-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/adm_local/unix/config_files/CMakeLists.txt b/adm_local/unix/config_files/CMakeLists.txt index 534b3d202..1028d562f 100755 --- a/adm_local/unix/config_files/CMakeLists.txt +++ b/adm_local/unix/config_files/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/adm_local/unix/config_files/check_GEOM.m4 b/adm_local/unix/config_files/check_GEOM.m4 index 2f07c5ae1..246e8e7e9 100644 --- a/adm_local/unix/config_files/check_GEOM.m4 +++ b/adm_local/unix/config_files/check_GEOM.m4 @@ -1,4 +1,4 @@ -dnl Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +dnl Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE dnl dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/adm_local/unix/config_files/check_GUI.m4 b/adm_local/unix/config_files/check_GUI.m4 index 96b244408..64ca1a605 100755 --- a/adm_local/unix/config_files/check_GUI.m4 +++ b/adm_local/unix/config_files/check_GUI.m4 @@ -1,4 +1,4 @@ -dnl Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +dnl Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE dnl dnl This library is free software; you can redistribute it and/or dnl modify it under the terms of the GNU Lesser General Public diff --git a/adm_local/unix/config_files/check_OpenCV.m4 b/adm_local/unix/config_files/check_OpenCV.m4 index a6950275b..1d313768c 100644 --- a/adm_local/unix/config_files/check_OpenCV.m4 +++ b/adm_local/unix/config_files/check_OpenCV.m4 @@ -1,4 +1,4 @@ -dnl Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +dnl Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE dnl dnl This library is free software; you can redistribute it and/or dnl modify it under the terms of the GNU Lesser General Public diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index 6ed9cc113..5c43bdefa 100755 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2012-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/bin/addvars2notebook_GEOM.py b/bin/addvars2notebook_GEOM.py index 49719a9cd..b3b4633d2 100644 --- a/bin/addvars2notebook_GEOM.py +++ b/bin/addvars2notebook_GEOM.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/bin/geom_setenv.py b/bin/geom_setenv.py index dc9e38de5..198196e6e 100644 --- a/bin/geom_setenv.py +++ b/bin/geom_setenv.py @@ -1,6 +1,6 @@ #! /usr/bin/env python # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 8bfe7cab7..beddf10e4 100755 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/doc/salome/CMakeLists.txt b/doc/salome/CMakeLists.txt index 1ccad11e2..88fb17859 100755 --- a/doc/salome/CMakeLists.txt +++ b/doc/salome/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index afd0a3a6a..c09d54e96 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/salome/examples/CTestTestfileInstall.cmake b/doc/salome/examples/CTestTestfileInstall.cmake index 9781ca583..0b25d65ff 100644 --- a/doc/salome/examples/CTestTestfileInstall.cmake +++ b/doc/salome/examples/CTestTestfileInstall.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2015 CEA/DEN, EDF R&D +# Copyright (C) 2015-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/salome/examples/testme.py b/doc/salome/examples/testme.py index 3e0e49698..6e3903fbc 100755 --- a/doc/salome/examples/testme.py +++ b/doc/salome/examples/testme.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/salome/gui/CMakeLists.txt b/doc/salome/gui/CMakeLists.txt index 38115b88b..2396b7fef 100755 --- a/doc/salome/gui/CMakeLists.txt +++ b/doc/salome/gui/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/doc/salome/gui/GEOM/CMakeLists.txt b/doc/salome/gui/GEOM/CMakeLists.txt index b765fe7ae..284495f14 100644 --- a/doc/salome/gui/GEOM/CMakeLists.txt +++ b/doc/salome/gui/GEOM/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2012-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/salome/gui/GEOM/collect_geom_methods.py b/doc/salome/gui/GEOM/collect_geom_methods.py index 2f489aefb..374e18071 100644 --- a/doc/salome/gui/GEOM/collect_geom_methods.py +++ b/doc/salome/gui/GEOM/collect_geom_methods.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2012-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/salome/gui/GEOM/doxyfile.in b/doc/salome/gui/GEOM/doxyfile.in index 5ab087422..de31b2b70 100755 --- a/doc/salome/gui/GEOM/doxyfile.in +++ b/doc/salome/gui/GEOM/doxyfile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/doc/salome/gui/GEOM/doxyfile_py.in b/doc/salome/gui/GEOM/doxyfile_py.in index c6532adc1..14da5e28d 100755 --- a/doc/salome/gui/GEOM/doxyfile_py.in +++ b/doc/salome/gui/GEOM/doxyfile_py.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/doc/salome/gui/GEOM/doxyfile_tui.in b/doc/salome/gui/GEOM/doxyfile_tui.in index 7b2bb9509..c81c72ea2 100755 --- a/doc/salome/gui/GEOM/doxyfile_tui.in +++ b/doc/salome/gui/GEOM/doxyfile_tui.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/doc/salome/gui/GEOM/static/footer.html b/doc/salome/gui/GEOM/static/footer.html index affd43d84..91afd6cc8 100755 --- a/doc/salome/gui/GEOM/static/footer.html +++ b/doc/salome/gui/GEOM/static/footer.html @@ -4,7 +4,7 @@
      $navpath
    diff --git a/doc/salome/tui/CMakeLists.txt b/doc/salome/tui/CMakeLists.txt index d716f2ae3..cb9fb8efc 100755 --- a/doc/salome/tui/CMakeLists.txt +++ b/doc/salome/tui/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/doc/salome/tui/doxyfile.in b/doc/salome/tui/doxyfile.in index a40c5d8d5..e488c67dc 100755 --- a/doc/salome/tui/doxyfile.in +++ b/doc/salome/tui/doxyfile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/doc/salome/tui/static/footer.html b/doc/salome/tui/static/footer.html index affd43d84..91afd6cc8 100755 --- a/doc/salome/tui/static/footer.html +++ b/doc/salome/tui/static/footer.html @@ -4,7 +4,7 @@
      $navpath
    diff --git a/idl/AdvancedGEOM.idl b/idl/AdvancedGEOM.idl index a10ac7319..5cf81a5f5 100644 --- a/idl/AdvancedGEOM.idl +++ b/idl/AdvancedGEOM.idl @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/idl/BREPPlugin.idl b/idl/BREPPlugin.idl index 26f276655..8bc249c6e 100644 --- a/idl/BREPPlugin.idl +++ b/idl/BREPPlugin.idl @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/idl/CMakeLists.txt b/idl/CMakeLists.txt index 61ae5ac62..3ec72cd2d 100755 --- a/idl/CMakeLists.txt +++ b/idl/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2012-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 777f3bcc3..31e6491a6 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/idl/GEOM_Superv.idl b/idl/GEOM_Superv.idl index a57977b01..c12b0104c 100644 --- a/idl/GEOM_Superv.idl +++ b/idl/GEOM_Superv.idl @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/idl/IGESPlugin.idl b/idl/IGESPlugin.idl index 8655edb1c..0394ada20 100644 --- a/idl/IGESPlugin.idl +++ b/idl/IGESPlugin.idl @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/idl/STEPPlugin.idl b/idl/STEPPlugin.idl index 9caf6f373..bbcfae2d8 100644 --- a/idl/STEPPlugin.idl +++ b/idl/STEPPlugin.idl @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/idl/STLPlugin.idl b/idl/STLPlugin.idl index 0f9da0012..e4f828a8c 100644 --- a/idl/STLPlugin.idl +++ b/idl/STLPlugin.idl @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/idl/VTKPlugin.idl b/idl/VTKPlugin.idl index 9c5593787..357610b69 100644 --- a/idl/VTKPlugin.idl +++ b/idl/VTKPlugin.idl @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/idl/XAOPlugin.idl b/idl/XAOPlugin.idl index 41720407b..16a470802 100644 --- a/idl/XAOPlugin.idl +++ b/idl/XAOPlugin.idl @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/resources/AdvancedGEOM.xml b/resources/AdvancedGEOM.xml index fee3b4138..cf955cf2b 100644 --- a/resources/AdvancedGEOM.xml +++ b/resources/AdvancedGEOM.xml @@ -1,7 +1,7 @@