# -*- coding: utf-8 -*-
#
# This file is subject to the terms and conditions defined in
# file 'LICENSE.txt', which is part of this source code package.
#
import numpy as np
import BasicTools.Helpers.ParserHelper as PH
from BasicTools.ImplicitGeometry.ImplicitGeometryFactory import RegisterClass
from BasicTools.ImplicitGeometry.ImplicitGeometryBase import ImplicitGeometryBase, smoothmin, smoothmax
[docs]class ImplicitGeometryUnion(ImplicitGeometryBase):
"""ImplicitGeometry Union of zones
z : zones
"""
def __init__(self,a=None):
super(ImplicitGeometryUnion,self).__init__()
if a is None:
self.Zones = []
else:
self.Zones = a
self.smoothControl = 0.0
[docs] def GetDistanceToPoint(self, pos):
op = ImplicitGeometryUnion.ApplyUnionOnLevelset
if len(self.Zones) == 1:
return self.ApplyInsideOut(self.Zones[0].GetDistanceToPoint(pos))
res = op(self.Zones[0].GetDistanceToPoint(pos),self.Zones[1].GetDistanceToPoint(pos),self.smoothControl)
for n in range(2,len(self.Zones)):
res = op(res,self.Zones[n].GetDistanceToPoint(pos),self.smoothControl)
return self.ApplyInsideOut(res)
[docs] @classmethod
def ApplyUnionOnLevelset(self,ls1,ls2,smoothControl=0):
if smoothControl == 0:
op = np.minimum
else:
def op(a,b):
return smoothmin(a,b,smoothControl)
return op(ls1,ls2)
def __str__(self):
res = "ImplicitGeometryUnion:\n"
for z in self.Zones:
res += " "+ str(z) + "\n"
return res
RegisterClass("Union",ImplicitGeometryUnion)
[docs]def CreateImplicitGeometryIntersection(ops):
obj = ImplicitGeometryIntersection()
obj.Zones = ops["Zones"]
return obj
[docs]class ImplicitGeometryIntersection(ImplicitGeometryBase):
"""ImplicitGeometry Intersection of zones
z : zones
"""
def __init__(self,z=None):
super(ImplicitGeometryIntersection,self).__init__()
self.Zones = z
self.smoothControl = 0.0
[docs] def GetDistanceToPoint(self, pos):
op = ImplicitGeometryIntersection().ApplyIntersectionOnLevelset
if len(self.Zones) == 1:
return self.ApplyInsideOut(self.Zones[0].GetDistanceToPoint(pos))
res = op(self.Zones[0].GetDistanceToPoint(pos),self.Zones[1].GetDistanceToPoint(pos),self.smoothControl)
for n in range(2,len(self.Zones)):
res = ImplicitGeometryIntersection().ApplyIntersectionOnLevelset(res,self.Zones[n].GetDistanceToPoint(pos),self.smoothControl)
return self.ApplyInsideOut(res)
[docs] @classmethod
def ApplyIntersectionOnLevelset(self,ls1,ls2,smoothControl=0):
if smoothControl == 0:
op = np.maximum
else:
def op(a,b):
return smoothmax(a,b,smoothControl)
return op(ls1,ls2)
RegisterClass("Intersection",ImplicitGeometryIntersection)
[docs]class ImplicitGeometryDifference(ImplicitGeometryBase):
"""ImplicitGeometry Difference of zones (z1-z2)
z1 : zone
z2 : zone
"""
def __init__(self,Zone1=None,Zone2=None):
super(ImplicitGeometryDifference,self).__init__()
self.Zone1 = Zone1
self.Zone2 = Zone2
self.smoothControl = 0
[docs] def GetDistanceToPoint(self, pos):
op = ImplicitGeometryDifference.ApplyDifferenceOnLevelset
res = op(self.Zone1.GetDistanceToPoint(pos),self.Zone2.GetDistanceToPoint(pos),self.smoothControl)
return self.ApplyInsideOut(res)
[docs] @classmethod
def ApplyDifferenceOnLevelset(self,ls1,ls2,smoothControl=0):
if smoothControl == 0:
def op(a,b):
return np.maximum(a,-b)
else:
def op(a,b):
return smoothmax(a,-b,smoothControl)
return op(ls1,ls2)
RegisterClass("Difference",ImplicitGeometryDifference)
[docs]def CreateImplicitGeometryOffset(ops):
res = ImplicitGeometryOffset()
if "Zones" in ops:
if len(ops["Zones"]) > 1 :
raise Exception("Cant treat more than one zone")
res.Zone1 = ops["Zones"][0]
PH.ReadProperties(ops, ["offset"], res)
return res
[docs]class ImplicitGeometryOffset(ImplicitGeometryBase):
"""ImplicitGeometry offset of the levelset
z : zone
offset : offset value (possitive shrink, negative grow )
"""
def __init__(self,a=None,val=0.):
super(ImplicitGeometryOffset,self).__init__()
self.Zone1 = a
self.offset = val
[docs] def GetDistanceToPoint(self, pos):
res = self.Zone1.GetDistanceToPoint(pos) + self.offset
return self.ApplyInsideOut(res)
RegisterClass("Offset",ImplicitGeometryOffset,CreateImplicitGeometryOffset)
[docs]def CreateImplicitGeometryInsideOut(ops):
res = ImplicitGeometryInsideOut()
if "Zones" in ops:
if len(ops["Zones"]) > 1 :
raise Exception("Cant treat more than one zone")
res.Zone1 = ops["Zones"][0]
return res
[docs]class ImplicitGeometryInsideOut(ImplicitGeometryBase):
"""ImplicitGeometry InsideOut of the levelset
z : zone
"""
def __init__(self,a=None,val=0.):
super(ImplicitGeometryInsideOut,self).__init__()
self.Zone1 = a
[docs] def GetDistanceToPoint(self, pos):
res = -self.Zone1.GetDistanceToPoint(pos)
return self.ApplyInsideOut(res)
RegisterClass("InsideOut",ImplicitGeometryInsideOut,CreateImplicitGeometryInsideOut)
[docs]def CreateImplicitGeometrySymmetric(ops):
res = ImplicitGeometrySymmetric()
if "Zones" in ops:
if len(ops["Zones"]) > 1 :
raise Exception("Cant treat more than one zone")
res.Zone1 = ops["Zones"][0]
PH.ReadProperties(ops, ["center"], res)
return res
[docs]class ImplicitGeometrySymmetric(ImplicitGeometryBase):
"""ImplicitGeometry Central Symmetriy of a zone
all point will be mapped to the first quadrant
z : zone
center : central point to compute the symetry
"""
def __init__(self,a=None):
super(ImplicitGeometrySymmetric,self).__init__()
self.Zone1 = a
self.center = np.array([0.,0.,0.])
[docs] def GetDistanceToPoint(self, pos):
res = self.Zone1.GetDistanceToPoint(np.abs(pos - self.center)+ self.center)
return self.ApplyInsideOut(res)
RegisterClass("Symmetric",ImplicitGeometrySymmetric,CreateImplicitGeometrySymmetric)
[docs]def CreateImplicitGeometryShell(ops):
res = ImplicitGeometryShell()
if "Zones" in ops:
if len(ops["Zones"]) > 1 :
raise Exception("Cant treat more than one zone")
res.Zone1 = ops["Zones"][0]
PH.ReadProperties(ops, ["thickness"], res)
return res
[docs]class ImplicitGeometryShell(ImplicitGeometryBase):
"""ImplicitGeometry Shell arround a zone
z : zone
thickness : thickness of the shell
"""
def __init__(self,a=None,val=0.):
super(ImplicitGeometryShell,self).__init__()
self.Zone1 = a
self.thickness = val
[docs] def GetDistanceToPoint(self, pos):
res = np.abs(self.Zone1.GetDistanceToPoint(pos) - self.thickness/2.) - self.thickness/2.
return self.ApplyInsideOut(res)
RegisterClass("Shell",ImplicitGeometryShell,CreateImplicitGeometryShell)
[docs]def CheckIntegrity(GUI=False):
def MustFail(func):
try:
func()
raise #pragma: no cover
except:
pass
from BasicTools.Containers.ConstantRectilinearMesh import ConstantRectilinearMesh
myMesh = ConstantRectilinearMesh()
myMesh.SetDimensions([5,6,7]);
myMesh.SetSpacing(1./(myMesh.GetDimensions()-1)*2);
myMesh.SetOrigin([-1.,-1.,-1.]);
myMesh.elements["hex8"].tags.CreateTag("2elems").SetIds([0,1])
myMesh.nodesTags.CreateTag("3points").SetIds([2,3,4])
print(myMesh)
OnePoint3D = np.array([1,2,3])
TwoPoints3D = np.array([[0.,0.,0.],[1.,2.,3.]], dtype=float)
import BasicTools.TestData as TestData
from functools import partial
from BasicTools.Helpers.Tests import TestTempDir
testDataPath = TestData.GetTestDataPath()
from BasicTools.ImplicitGeometry.ImplicitGeometryObjects import ImplicitGeometrySphere
SP1 = ImplicitGeometrySphere(center=[0,0,0],radius=1.)
SPX = ImplicitGeometrySphere(center=[0.5,0,0],radius=1.)
SPY = ImplicitGeometrySphere(center=[0,0.5,0],radius=1.)
########################### ImplicitGeometryUnion #######################
IGUnion =ImplicitGeometryUnion([SP1,SPX,SPY])
IGUnion(myMesh)
IGUnion.smoothControl = 0.1
IGUnion(myMesh)
print(IGUnion)
IGUnion =ImplicitGeometryUnion([SPY])
IGUnion(myMesh)
########################### ImplicitGeometryIntersection #######################
IGIntersection =ImplicitGeometryIntersection([SP1,SPX,SPY])
IGIntersection(myMesh)
IGIntersection.smoothControl = 0.1
IGIntersection(myMesh)
print(IGIntersection)
IGIntersection = CreateImplicitGeometryIntersection({"Zones":[SP1]})
IGIntersection(myMesh)
########################### ImplicitGeometryDifference #######################
IGDifference =ImplicitGeometryDifference(Zone1=SP1,Zone2=SPX)
IGDifference(myMesh)
IGDifference.smoothControl = 0.1
IGDifference(myMesh)
print(IGDifference)
########################### ImplicitGeometryOffset #######################
IGOffset = CreateImplicitGeometryOffset({"Zones":[IGUnion],"offset":0.1})
IGOffset(myMesh)
MustFail(partial(CreateImplicitGeometryOffset, {"Zones":[IGUnion,IGUnion],"offset":0.1}))
########################### ImplicitGeometrySymmetric #######################
IGSymmetric = CreateImplicitGeometrySymmetric({"Zones":[SPX]})
IGSymmetric(myMesh)
MustFail(partial(CreateImplicitGeometrySymmetric, {"Zones":[IGUnion,IGUnion]}))
########################### ImplicitGeometryShell #######################
IGShell = CreateImplicitGeometryShell({"Zones":[IGUnion],"thickness":0.1})
IGShell(myMesh)
MustFail(partial(CreateImplicitGeometryShell, {"Zones":[IGUnion,IGUnion],"thickness":0.1}))
########################### ImplicitGeometryInsideOut #######################
IGIO = CreateImplicitGeometryInsideOut({"Zones":[IGUnion]})
IGIO(myMesh)
MustFail(partial(CreateImplicitGeometryInsideOut, {"Zones":[IGUnion,IGUnion]}))
return "ok"
if __name__ == '__main__':# pragma: no cover
print(CheckIntegrity(GUI=False))