From e8719849800572f419443b38aa891ce5073abe99 Mon Sep 17 00:00:00 2001 From: benoit128 Date: Thu, 19 Dec 2024 09:30:48 +0100 Subject: [PATCH] Generator: add recoverBC for tetraMesher --- Cassiopee/CPlot/apps/tkBC.py | 23 +++++- Cassiopee/CPlot/apps/tkTransform.py | 93 ++++++++++++++++++++----- Cassiopee/Generator/Generator/PyTree.py | 13 +++- 3 files changed, 108 insertions(+), 21 deletions(-) diff --git a/Cassiopee/CPlot/apps/tkBC.py b/Cassiopee/CPlot/apps/tkBC.py index d2c6d73cc..031bf78cd 100644 --- a/Cassiopee/CPlot/apps/tkBC.py +++ b/Cassiopee/CPlot/apps/tkBC.py @@ -582,9 +582,6 @@ def rmBCOfType(): #============================================================================== def setBCWith(): if CTK.t == []: return - if CTK.__MAINTREE__ != CTK.UNDEFINEDBC: - CTK.TXT.insert('START', 'Fail on a this tree (view undefined BC before).\n') - CTK.TXT.insert('START', 'Error: ', 'Error'); return nzs = CPlot.getSelectedZones() if nzs == []: return @@ -593,6 +590,26 @@ def setBCWith(): nameBC = typeBC; typeBC = 'FamilySpecified:'+typeBC else: nameBC = typeBC + # On CAD tree, we set directly BC to full zone + if CTK.CADHOOK is not None: + CTK.saveTree() + CTK.setCursor(2, WIDGETS['setBCWith']) + for nz in nzs: + nob = CTK.Nb[nz]+1 + noz = CTK.Nz[nz] + z = CTK.t[2][nob][2][noz] + dim = Internal.getZoneDim(z) + C._addBC2Zone(z, nameBC, typeBC, elementRange=[0,dim[2]]) + CTK.TXT.insert('START', 'BCs set to %s.\n'%typeBC) + CTK.TKTREE.updateApp() + CTK.setCursor(0, WIDGETS['setBCWith']) + return + + # On volume tree, we set from undefinedbc + if CTK.__MAINTREE__ != CTK.UNDEFINEDBC: + CTK.TXT.insert('START', 'Fail on a this tree (view undefined BC before).\n') + CTK.TXT.insert('START', 'Error: ', 'Error'); return + node = Internal.getNodeFromName(CTK.t, 'EquationDimension') if node is not None: ndim = Internal.getValue(node) else: diff --git a/Cassiopee/CPlot/apps/tkTransform.py b/Cassiopee/CPlot/apps/tkTransform.py index 0c9d1aa3b..81b37cdb9 100644 --- a/Cassiopee/CPlot/apps/tkTransform.py +++ b/Cassiopee/CPlot/apps/tkTransform.py @@ -10,6 +10,7 @@ import CPlot.Tk as CTK import KCore.Vector as Vector import Converter.Internal as Internal +import CPlot.Panels as Panels import time # local widgets list @@ -119,17 +120,35 @@ def rotate(event=None): # update CAD if necessary if CTK.CADHOOK is not None: - if len(nzs) == len(Internal.getZones(CTK.t)): - import OCC - print('rotate cad') - OCC.occ.rotate(CTK.CADHOOK, X, axe, angle) + import OCC.PyTree as OCC + faceList = [] + for nz in nzs: + nob = CTK.Nb[nz]+1 + noz = CTK.Nz[nz] + z = CTK.t[2][nob][2][noz] + no = OCC.getNo(z) + faceList.append(no) + faceList = [] # forced for debug + if len(faceList) == len(Internal.getZones(CTK.t)): faceList = [] + OCC.occ.rotate(CTK.CADHOOK, X, axe, angle, faceList) + if faceList != []: + [hmin, hmax, hausd] = OCC.getCADcontainer(CTK.t) + edges = Internal.getNodeFromName1(CTK.t, 'EDGES') + edges[2] = [] + faces = Internal.getNodeFromName1(CTK.t, 'FACES') + faces[2] = [] + OCC._meshAllEdges(CTK.CADHOOK, CTK.t, hmin=hmin, hmax=hmax, hausd=hausd) # loose manual remeshing + OCC._meshAllFacesTri(CTK.CADHOOK, CTK.t, hmin=hmin, hmax=hmax, hausd=hausd) + (CTK.Nb, CTK.Nz) = CPlot.updateCPlotNumbering(CTK.t) + CTK.TKTREE.updateApp() + CTK.display(CTK.t) CTK.TXT.insert('START', 'Zones have been rotated.\n') CTK.TKTREE.updateApp() CPlot.render() #============================================================================== -def translate(): +def translate(event=None): if CTK.t == []: return if CTK.__MAINTREE__ <= 0: CTK.TXT.insert('START', 'Fail on a temporary tree.\n') @@ -169,10 +188,29 @@ def translate(): # update CAD if necessary if CTK.CADHOOK is not None: - if len(nzs) == len(Internal.getZones(CTK.t)): - import OCC - print('translating cad') - OCC.occ.translate(CTK.CADHOOK, (v[0], v[1], v[2])) + import OCC.PyTree as OCC + faceList = [] + for nz in nzs: + nob = CTK.Nb[nz]+1 + noz = CTK.Nz[nz] + z = CTK.t[2][nob][2][noz] + no = OCC.getNo(z) + faceList.append(no) + faceList = [] # forced for debug + if len(faceList) == len(Internal.getZones(CTK.t)): faceList = [] + OCC.occ.translate(CTK.CADHOOK, (v[0], v[1], v[2]), faceList) + if faceList != []: + [hmin, hmax, hausd] = OCC.getCADcontainer(CTK.t) + edges = Internal.getNodeFromName1(CTK.t, 'EDGES') + edges[2] = [] + faces = Internal.getNodeFromName1(CTK.t, 'FACES') + faces[2] = [] + OCC._meshAllEdges(CTK.CADHOOK, CTK.t, hmin=hmin, hmax=hmax, hausd=hausd) # loose manual remeshing + OCC._meshAllFacesTri(CTK.CADHOOK, CTK.t, hmin=hmin, hmax=hmax, hausd=hausd) + (CTK.Nb, CTK.Nz) = CPlot.updateCPlotNumbering(CTK.t) + CTK.TKTREE.updateApp() + CTK.display(CTK.t) + CTK.TXT.insert('START', 'Zones have been translated.\n') CTK.TKTREE.updateApp() @@ -227,7 +265,7 @@ def translateClick(): TTK.raiseButton(w) #============================================================================== -def scale(): +def scale(event=None): if CTK.t == []: return if CTK.__MAINTREE__ <= 0: CTK.TXT.insert('START', 'Fail on a temporary tree.\n') @@ -290,11 +328,30 @@ def scale(): CTK.replace(CTK.t, nob, noz, a) # update CAD if necessary - if CTK.CADHOOK is not None: - if len(nzs) == len(Internal.getZones(CTK.t)) and len(v) == 1: - import OCC - print('scale cad') - OCC.occ.scale(CTK.CADHOOK, v[0], X) + if CTK.CADHOOK is not None and len(v) == 1: + import OCC.PyTree as OCC + faceList = [] + for nz in nzs: + nob = CTK.Nb[nz]+1 + noz = CTK.Nz[nz] + z = CTK.t[2][nob][2][noz] + no = OCC.getNo(z) + faceList.append(no) + faceList = [] # forced for debug + if len(faceList) == len(Internal.getZones(CTK.t)): faceList = [] + OCC.occ.scale(CTK.CADHOOK, v[0], X, faceList) + if faceList != []: + [hmin, hmax, hausd] = OCC.getCADcontainer(CTK.t) + edges = Internal.getNodeFromName1(CTK.t, 'EDGES') + edges[2] = [] + faces = Internal.getNodeFromName1(CTK.t, 'FACES') + faces[2] = [] + OCC._meshAllEdges(CTK.CADHOOK, CTK.t, hmin=hmin, hmax=hmax, hausd=hausd) # loose manual remeshing + OCC._meshAllFacesTri(CTK.CADHOOK, CTK.t, hmin=hmin, hmax=hmax, hausd=hausd) + (CTK.Nb, CTK.Nz) = CPlot.updateCPlotNumbering(CTK.t) + CTK.TKTREE.updateApp() + CTK.display(CTK.t) + CTK.TXT.insert('START', 'Zones have been scaled.\n') CTK.TKTREE.updateApp() @@ -395,8 +452,9 @@ def createApp(win): B.grid(row=0, column=1, sticky=TK.EW) B = TTK.Entry(Frame, textvariable=VARS[0], background='White', width=5) B.grid(row=0, column=2, columnspan=1, sticky=TK.EW) + B.bind('', translate) BB = CTK.infoBulle(parent=B, text='Translation vector.') - + # - Translate from here to here - B = TTK.Button(Frame, text="Translate by clicking", command=translateClick) B.grid(row=1, column=0, columnspan=3, sticky=TK.EW) @@ -412,6 +470,7 @@ def createApp(win): B = TTK.OptionMenu(Frame, VARS[5], 'along XYZ', 'along view') B.grid(row=2, column=1, sticky=TK.EW) B = TTK.Entry(Frame, textvariable=VARS[1], background='White', width=5) + B.bind('', scale) B.grid(row=2, column=2, sticky=TK.EW) BB = CTK.infoBulle(parent=B, text='Scale factors (+ optionally center for scaling): uniform f value or fx;fy;fz (+ optionally cx;cy;cz)\nFor automatic adimensioning, use 0.') @@ -424,6 +483,7 @@ def createApp(win): 'around Z', 'around view') B.grid(row=3, column=1, sticky=TK.EW) B = TTK.Entry(Frame, textvariable=VARS[3], background='White', width=5) + B.bind('', rotate) B.grid(row=3, column=2, sticky=TK.EW) BB = CTK.infoBulle(parent=B, text='angle (degrees) or \nangle; Xc;Yc;Zc (angle+rotation center)\nIf center is not specified, rotate around barycenter of zones.') @@ -444,6 +504,7 @@ def createApp(win): B = TTK.OptionMenu(Frame, VARS[7], 'cart2Cyl', 'cyl2Cart') B.grid(row=5, column=1, sticky=TK.EW) B = TTK.Entry(Frame, textvariable=VARS[8], background='White') + B.bind('', changeFrame) B.grid(row=5, column=2, sticky=TK.EW) BB = CTK.infoBulle(parent=B, text='Origin: x0;y0;z0\nAxis: tx;ty;tz.') diff --git a/Cassiopee/Generator/Generator/PyTree.py b/Cassiopee/Generator/Generator/PyTree.py index 93ee8fbc8..f675460f5 100644 --- a/Cassiopee/Generator/Generator/PyTree.py +++ b/Cassiopee/Generator/Generator/PyTree.py @@ -338,13 +338,22 @@ def T3mesher2D(a, grading=1.2, triangulateOnly=0, metricInterpType=0): return C.convertArrays2ZoneNode('tri', [c]) def tetraMesher(a, maxh=-1., grading=0.4, triangulateOnly=0, - remeshBoundaries=0, algo=1, optionString=""): + remeshBoundaries=0, algo=1, optionString="", recoverBC=False): """Create a TRI/TETRA mesh given a set of BAR or surfaces in a. Usage: tetraMesher(a, fineness, grading)""" + if recoverBC: + zbcs=[]; bcnames=[]; bctypes=[] + for z in Internal.getZones(a): + b = C.getBCs(z, extrapFlow=False) + zbcs += b[0]; bcnames += b[1]; bctypes += b[2] + gbcs = (zbcs, bcnames, bctypes) c = C.getFields('coords', a) c = Generator.tetraMesher(c, maxh, grading, triangulateOnly, remeshBoundaries, algo, optionString) - return C.convertArrays2ZoneNode('mesh', [c]) + z = C.convertArrays2ZoneNode('mesh', [c]) + if recoverBC: + C._recoverBCs(z, gbcs) + return z def gapfixer(contour, cloud, hardPoints=None, refine=1): """Fix a gap defined by a contour bar and a point cloud representing the gap surface.