From 24a99df4ef01e69754da1ed628ae66c540e1fc54 Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 13:18:03 +0200 Subject: [PATCH 01/29] =?UTF-8?q?OCC.Utils=20=5Freally=5F=20is=20no=20plac?= =?UTF-8?q?e=20for=20DataExchange,=20is=20showing=20a=20poor=20sense=20of?= =?UTF-8?q?=20structure=20(=20how=20is=20data=20exchange,=20loading=20CAD?= =?UTF-8?q?=20files=20a=20utility=3F=20)=E2=80=A6=20very=20counterintuitiv?= =?UTF-8?q?e=E2=80=A6=20I've=20added=20a=20fast=20loading=20STL=20module.?= =?UTF-8?q?=20Something=20rather=20silly=20in=20the=20other=20STL.py=20is?= =?UTF-8?q?=20that=20the=20STL=20mesh=20is=20converted=20to=20BRep's?= =?UTF-8?q?=E2=80=A6=20so=20this=20explains=20the=20=5Fvery=5F=20poor=20pe?= =?UTF-8?q?rformance=20of=20STL.py=20Therefore=20its=20a=20very=20good=20i?= =?UTF-8?q?dea=20to=20have=20"XSDRAWSTLVRML=5FDataSource"=20wrapped=20befo?= =?UTF-8?q?re=20releasing=200.6,=20since=20then=20this=20version=20should?= =?UTF-8?q?=20become=20the=20default=20STL=20loader.=20Its=2010=20-=20100*?= =?UTF-8?q?=20times=20faster=20;)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/addons/{Utils => }/DataExchange/IGES.py | 0 src/addons/{Utils => }/DataExchange/STEP.py | 0 src/addons/{Utils => }/DataExchange/STL.py | 0 src/addons/DataExchange/STL_fast.py | 104 ++++++++++++++++++ .../{Utils => }/DataExchange/__init__.py | 0 src/addons/{Utils => }/DataExchange/utils.py | 0 6 files changed, 104 insertions(+) rename src/addons/{Utils => }/DataExchange/IGES.py (100%) rename src/addons/{Utils => }/DataExchange/STEP.py (100%) rename src/addons/{Utils => }/DataExchange/STL.py (100%) create mode 100644 src/addons/DataExchange/STL_fast.py rename src/addons/{Utils => }/DataExchange/__init__.py (100%) rename src/addons/{Utils => }/DataExchange/utils.py (100%) diff --git a/src/addons/Utils/DataExchange/IGES.py b/src/addons/DataExchange/IGES.py similarity index 100% rename from src/addons/Utils/DataExchange/IGES.py rename to src/addons/DataExchange/IGES.py diff --git a/src/addons/Utils/DataExchange/STEP.py b/src/addons/DataExchange/STEP.py similarity index 100% rename from src/addons/Utils/DataExchange/STEP.py rename to src/addons/DataExchange/STEP.py diff --git a/src/addons/Utils/DataExchange/STL.py b/src/addons/DataExchange/STL.py similarity index 100% rename from src/addons/Utils/DataExchange/STL.py rename to src/addons/DataExchange/STL.py diff --git a/src/addons/DataExchange/STL_fast.py b/src/addons/DataExchange/STL_fast.py new file mode 100644 index 000000000..500e16aef --- /dev/null +++ b/src/addons/DataExchange/STL_fast.py @@ -0,0 +1,104 @@ +import os +from OCC.RWStl import RWStl +from OCC.MeshVS import MeshVS_Mesh +from OCC.OSD import OSD_Path +from OCC.TCollection import TCollection_AsciiString + + +#=============================================================================== +# Currently -alas- the fast STL mesh loader relies on SMESH as a dependency +# It would be _very_ fortunate to wrap "XSDRAWSTLVRML_DataSource" +# since that would allow to do away with this dependency injection +# also, this is the "right" choice in terms of API... +# adapted from: http://www.opencascade.org/org/forum/thread_9793/?forum=3 +#=============================================================================== + + +# _stl_file = '/Users/localadmin/Documents/workspace/pythonocc/data/_3dmodels/aube_pleine.stl' +# def _load_stl_data(_pth): +# +# assert os.path.isfile(_stl_file), 'not a valid path {0}'.format(_stl_file) +# +# _ascii_str = TCollection_AsciiString(_stl_file) +# _osd_pth = OSD_Path(_ascii_str) +# aSTLMesh = RWStl.ReadFile(_osd_pth).GetObject() +# return aSTLMesh + +# def draw_stl_file(display): +# +# +# Handle(StlMesh_Mesh) aSTLMesh = RWStl::ReadFile(aFile); +# Handle( MeshVS_Mesh ) aMesh = new MeshVS_Mesh(); +# Handle( XSDRAWSTLVRML_DataSource ) aDS = new XSDRAWSTLVRML_DataSource( aSTLMesh ); +# +# aMesh->SetDataSource(aDS); +# aMesh->AddBuilder( new MeshVS_MeshPrsBuilder( aMesh), Standard_True );//False -> No selection +# +# aMesh->GetDrawer()->SetBoolean(MeshVS_DA_DisplayNodes,Standard_False); //MeshVS_DrawerAttribute +# aMesh->GetDrawer()->SetBoolean(MeshVS_DA_ShowEdges,Standard_False); +# aMesh->GetDrawer()->SetMaterial(MeshVS_DA_FrontMaterial,DEFAULT_MATERIAL); +# +# +# aMesh->SetColor(Quantity_NOC_AZURE); +# aMesh->SetDisplayMode( MeshVS_DMF_Shading ); // Mode as defaut +# aMesh->SetHilightMode( MeshVS_DMF_WireFrame ); // Wireframe as default hilight mode +# +# myDoc->m_AISContext->Display(aMesh); + + + +import os +from OCC.Graphic3d import Graphic3d_MaterialAspect, Graphic3d_NOM_SATIN +from OCC.MeshVS import MeshVS_Mesh, MeshVS_MeshPrsBuilder, MeshVS_DA_FrontMaterial, MeshVS_DA_DisplayNodes, MeshVS_DA_ShowEdges, MeshVS_DA_SmoothShading, MeshVS_DA_Reflection +from OCC.SMESH import SMESH_Gen, SMESH_MeshVSLink + + +def get_fast_stl_mesh_from_path(_path): + """ + open/parse STL file and get the resulting TopoDS_Shape instance + """ + gen = SMESH_Gen() + mesh = gen.CreateMesh(0, True) + # .STLToMesh does a poor job in catching errors, so let's check the path... + if not os.path.isfile(_path): + raise ValueError("{0} is not a valid path".format(_path)) + mesh.STLToMesh(_path) + # test for a minimal number of mesh vertices + if mesh.NbNodes() < 1: + raise ValueError("stl file {0} contains no geometry".format(_path)) + + aDS = SMESH_MeshVSLink(mesh) + aMeshVS = MeshVS_Mesh(True) + DMF = 2 # to wrap; 1 is wireframe + MeshVS_BP_Mesh = 5 # To wrap! + aPrsBuilder = MeshVS_MeshPrsBuilder(aMeshVS.GetHandle(),DMF,aDS.GetHandle()) #,0,MeshVS_BP_Mesh) + + aMeshVS.SetDataSource(aDS.GetHandle()) + aMeshVS.AddBuilder(aPrsBuilder.GetHandle(),False) + MeshVS_DMF_HilightPrs = int(0x0400) + MeshVS_DMF_Wireframe = int(0x0001) + MeshVS_DMF_Shading = int(0x0002) + aMeshVS.SetDisplayMode(MeshVS_DMF_Shading) # 1 -> wireframe, 2 -> shaded +# aMeshVS.SetDisplayMode(MeshVS_DMF_Wireframe) # 1 -> wireframe, 2 -> shaded + # aMeshVS.SetColor(Quantity_NOC_AZURE) + #Create the graphic window and display the mesh + mesh_to_display = aMeshVS.GetHandle() + # display the mesh edges in black + mesh_drawer = aMeshVS.GetDrawer().GetObject() + # Edges in black + # mesh_drawer.SetColor(3,Quantity_Color(Quantity_NOC_BLACK))# 3 means Edge color + # Markers in green + # mesh_drawer.SetColor(13,Quantity_Color(Quantity_NOC_GREEN)) + print 'got it, just setting params' + mesh_drawer.SetMaterial(MeshVS_DA_FrontMaterial, Graphic3d_MaterialAspect(Graphic3d_NOM_SATIN)) + mesh_drawer.SetBoolean( MeshVS_DA_DisplayNodes, False) + mesh_drawer.SetBoolean( MeshVS_DA_ShowEdges, False) + mesh_drawer.SetBoolean( MeshVS_DA_SmoothShading, True) +# mesh_drawer.SetBoolean( MeshVS_DA_SmoothShading, False) + mesh_drawer.SetBoolean( MeshVS_DA_Reflection, True) + # mesh_drawer.SetColor( MeshVS_DA_InteriorColor, Quantity_Color(Quantity_NOC_AZURE)) + # mesh_drawer.SetBoolean(MeshVS_DA_ColorReflection, True) + msh = mesh_to_display.GetObject() + print 'msh:', msh + return msh + diff --git a/src/addons/Utils/DataExchange/__init__.py b/src/addons/DataExchange/__init__.py similarity index 100% rename from src/addons/Utils/DataExchange/__init__.py rename to src/addons/DataExchange/__init__.py diff --git a/src/addons/Utils/DataExchange/utils.py b/src/addons/DataExchange/utils.py similarity index 100% rename from src/addons/Utils/DataExchange/utils.py rename to src/addons/DataExchange/utils.py From b0bcc2aa39e8b12f7137b1313ecfe49d74108e5f Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 13:24:39 +0200 Subject: [PATCH 02/29] loading the backends was handled in a really silly way. for instance, I have all the backend installed and in the previous version _all_ these backend would get loaded! serious overhead... so, pythonocc is now more selective about loading the backend and does so in a logical order. fixed the menu bar issue, and added a method that centers the window and sizes the window, depending on the resolution of the screen ( i got a retina screen ;) ) --- src/addons/Display/SimpleGui.py | 141 +++++++++++++++++++++----------- 1 file changed, 91 insertions(+), 50 deletions(-) diff --git a/src/addons/Display/SimpleGui.py b/src/addons/Display/SimpleGui.py index d7d4146e3..99fe31918 100644 --- a/src/addons/Display/SimpleGui.py +++ b/src/addons/Display/SimpleGui.py @@ -20,45 +20,50 @@ import sys import os, os.path from OCC import VERSION -# First check which GUI library to use -# Check wxPython -try: - import wx - HAVE_WX = True -except: - HAVE_WX = False -# Check PyQt -try: - from PyQt4 import QtCore, QtGui - HAVE_QT = True -except: - HAVE_QT = False - -# Then define the default backend -if HAVE_WX: - DEFAULT_BACKEND = 'wx' -elif HAVE_QT: - DEFAULT_BACKEND = 'qt' -else: #use Tk backend - DEFAULT_BACKEND = 'Tk' - import Tkinter -# By default, used backend is the default_backend -USED_BACKEND = DEFAULT_BACKEND - -def set_backend(str_backend): - ''' Overload the default used backend - ''' - global USED_BACKEND - # make str_backend case unsensitive - str_backend = str_backend.lower() - if str_backend not in ['wx','qt','x']: - raise AssertionError('Backend must either be "wx", "qt" or "x"') - elif str_backend == 'qt' and not HAVE_QT: - raise Assertion('PyQt library not installed or not found.') - elif str_backend == 'wx' and not HAVE_WX: - raise Assertion('wxPython library not installed or not found.') + + +def get_backend(): + """ + + loads a backend + backends are loaded in order of preference + since python comes with Tk included, but that PySide or PyQt4 is much preferred + ( which is a bias of the PythonOCC developers ) + + """ + + # Check PyQt + try: + from PyQt4 import QtCore, QtGui + return 'pyqt4' + except: + pass + + try: + from PySide import QtCore, QtGui + return 'pyside' + except: + pass + # Check wxPython + try: + import wx + return 'wx' + except: + pass + + if sys.platform == 'darwin': + # Tk is not an option, since we on osx a modern Cocoa backend is required + raise ValueError("PythonOCC needs PySide of PyQt4 as a gui backend. wxPython 2.9, using cocoa is an option, but not recommended") + else: - USED_BACKEND = str_backend + # use Tk backend as a fall back... + # note, this is X11 territory, so no go area for osx... since this relies on the Cocoa backend + try: + import Tkinter + return 'tkinter' + except: + raise ValueError("No compliant GUI library found. You must have either PySide, PyQt4, wxPython or Tkinter installed.") + sys.exit(1) def get_bg_abs_filename(): ''' Returns the absolute file name for the file default_background.bmp @@ -70,17 +75,27 @@ def get_bg_abs_filename(): else: return bg_abs_filename -def safe_yield(): +def safe_yield(USED_BACKEND): if USED_BACKEND == 'wx': + import wx wx.SafeYield() - elif USED_BACKEND == 'qt': + elif USED_BACKEND == 'pyqt4': + from PyQt4 import QtGui #QtCore.processEvents() QtGui.QApplication.processEvents() - + elif USED_BACKEND == 'pyside': + from PySide import QtGui + #QtCore.processEvents() + QtGui.QApplication.processEvents() + def init_display(): global display, add_menu, add_function_to_menu, start_display, app, win + + USED_BACKEND = get_backend() + # wxPython based simple GUI if USED_BACKEND == 'wx': + import wx from wxDisplay import wxViewer3d class AppFrame(wx.Frame): @@ -122,7 +137,14 @@ def start_display(): app.MainLoop() # PyQt based simple GUI - elif USED_BACKEND == 'qt': + elif USED_BACKEND == 'pyqt4' or USED_BACKEND=='pyside': + + # dont really get why its nessecary to import yet again... sigh... + if USED_BACKEND == "pyqt4": + from PyQt4 import QtGui, QtCore + else: + from PySide import QtGui, QtCore + from qtDisplay import qtViewer3d class MainWindow(QtGui.QMainWindow): def __init__(self, *args): @@ -131,18 +153,39 @@ def __init__(self, *args): self.setWindowTitle("pythonOCC-%s 3d viewer ('qt' backend)"%VERSION) self.resize(1024,768) self.setCentralWidget(self.canva) - self.menuBar = self.menuBar() + if not sys.platform == 'darwin': + self.menu_bar = self.menuBar() + else: + # create a parentless menubar + # see: http://stackoverflow.com/questions/11375176/qmenubar-and-qmenu-doesnt-show-in-mac-os-x?lq=1 + # noticeable is that the menu ( alas ) is created in the topleft of the screen, just + # next to the apple icon + # still does ugly things like showing the "Python" menu in bold + self.menu_bar = QtGui.QMenuBar() self._menus = {} self._menu_methods = {} + # place the window in the center of the screen, at half the screen size + self.centerOnScreen() + + def centerOnScreen (self): + '''Centers the window on the screen.''' + resolution = QtGui.QDesktopWidget().screenGeometry() + self.move( + (resolution.width() / 2) - (self.frameSize().width() / 2), + (resolution.height() / 2) - (self.frameSize().height() / 2) + ) def add_menu(self, menu_name): - _menu = self.menuBar.addMenu("&"+menu_name) + _menu = self.menu_bar.addMenu("&"+menu_name) self._menus[menu_name]=_menu def add_function_to_menu(self, menu_name, _callable): assert callable(_callable), 'the function supplied is not callable' try: _action = QtGui.QAction(_callable.__name__.replace('_', ' ').lower(), self) + # if not, the "exit" action is now shown... + # Qt is trying so hard to be native cocoa'ish that its a nuisance + _action.setMenuRole(QtGui.QAction.NoRole) self.connect(_action, QtCore.SIGNAL("triggered()"), _callable) self._menus[menu_name].addAction(_action) except KeyError: @@ -158,9 +201,11 @@ def add_menu(*args, **kwargs): def add_function_to_menu(*args, **kwargs): win.add_function_to_menu(*args, **kwargs) def start_display(): + win.raise_() # make the application float to the top app.exec_() elif USED_BACKEND == 'Tk': + import Tkinter from tkDisplay import tkViewer3d app = Tkinter.Tk() win = tkViewer3d(app) @@ -172,19 +217,15 @@ def add_menu(*args, **kwargs): pass def add_function_to_menu(*args, **kwargs): pass - else: - print "No compliant GUI library found. You must have either wxPython, PyQt or python-xlib installed." - sys.exit(0) return display, start_display, add_menu, add_function_to_menu if __name__ == '__main__': - set_backend('x') init_display() from OCC.BRepPrimAPI import * def sphere(event=None): - display.DisplayShape(BRepPrimAPI_MakeSphere(1).Shape()) + display.DisplayShape(BRepPrimAPI_MakeSphere(1).Shape(), update=True) def cube(event=None): - display.DisplayShape(BRepPrimAPI_MakeBox(1,1,1).Shape()) + display.DisplayShape(BRepPrimAPI_MakeBox(1,1,1).Shape(), update=True) def exit(event=None): sys.exit() add_menu('primitives') From 3b5076531dc1fc3618c778bf36ea2bfb886bea73 Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 13:39:49 +0200 Subject: [PATCH 03/29] =?UTF-8?q?the=20latest=20version=20of=20KBE?= =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/addons/KBE/__init__.py | 4 + src/addons/KBE/base.py | 151 ++++++++------- src/addons/KBE/edge.py | 307 +++++++++++++++++++++++-------- src/addons/KBE/face.py | 330 +++++++++++++++++---------------- src/addons/KBE/plane.py | 42 +++++ src/addons/KBE/scratchpad.py | 5 + src/addons/KBE/shell.py | 76 ++++++++ src/addons/KBE/solid.py | 61 +----- src/addons/KBE/types_lut.py | 347 +++++++++++++++++++---------------- src/addons/KBE/vertex.py | 90 ++++++--- src/addons/KBE/wire.py | 16 ++ 11 files changed, 890 insertions(+), 539 deletions(-) create mode 100644 src/addons/KBE/plane.py create mode 100644 src/addons/KBE/scratchpad.py create mode 100644 src/addons/KBE/shell.py create mode 100644 src/addons/KBE/wire.py diff --git a/src/addons/KBE/__init__.py b/src/addons/KBE/__init__.py index e69de29bb..13acd6762 100644 --- a/src/addons/KBE/__init__.py +++ b/src/addons/KBE/__init__.py @@ -0,0 +1,4 @@ +#from vertex import Vertex +#from edge import Edge +#from face import Face +#from solid import Shell, Solid \ No newline at end of file diff --git a/src/addons/KBE/base.py b/src/addons/KBE/base.py index 8fa30e8c1..b2c250fdc 100644 --- a/src/addons/KBE/base.py +++ b/src/addons/KBE/base.py @@ -17,35 +17,18 @@ Can be a module, class or namespace. ''' - +# occ +from OCC.BRepBuilderAPI import BRepBuilderAPI_Copy +from OCC.BRepGProp import BRepGProp +from OCC.BRepCheck import * +# occ high level +from OCC.Display.SimpleGui import init_display +from OCC.Utils.Construct import * +# KBE +from types_lut import shape_lut, topo_lut, orient_lut, state_lut, curve_lut, surface_lut +# stdlib import functools -from OCC.gp import * - -from OCC.TopoDS import * -from OCC.Geom import * -from OCC.BRep import * -# for projection -from OCC.GeomAPI import * -from OCC.Extrema import * -# for checking if a surface is planar -from OCC.GeomLib import * -from OCC.TopExp import * -from OCC.BRepBuilderAPI import * - -# for generalizing edges/curves/analytic types -from OCC.Adaptor2d import * -from OCC.Adaptor3d import * -# we'll use this, really -from OCC.BRepAdaptor import * - -from OCC.GCPnts import * - -#=============================================================================== -# HELPER CLASSES -#=============================================================================== -from OCC.KBE.types_lut import GeometryLookup, ShapeToTopology -from OCC.Utils.Construct import * #=============================================================================== # DISPLAY @@ -66,7 +49,6 @@ def __call__(self, *args, **kwargs): @singleton class Display(object): def __init__(self): - from OCC.Display.SimpleGui import init_display self.display, self.start_display, self.add_menu, self.add_function_to_menu = init_display() def __call__(self, *args, **kwargs): return self.display.DisplayShape(*args, **kwargs) @@ -74,17 +56,17 @@ def __call__(self, *args, **kwargs): #============ # base class #============ + """base class for all KBE objects""" class KbeObject(object): - """base class for all KBE objects""" def __init__(self, name=None): """Constructor for KbeObject""" + self.GlobalProperties = GlobalProperties(self) self.name = name self._dirty = False - self._topods = None - self._topo_type = None # defined in concrete class __init__ method - self.tolerance = 1e-7 + self.tolerance = TOLERANCE + self.display_set = False @property def is_dirty(self): @@ -96,33 +78,56 @@ def is_dirty(self, _bool): self._dirty = bool(_bool) @property - def topo(self): - '''return the TopoDS_* object + def topo_type(self): + return topo_lut[self.ShapeType()] - updates when dirty + @property + def geom_type(self): + if self.topo_type == 'edge': + return curve_lut[self.ShapeType()] + if self.topo_type == 'face': + return surface_lut[self.adaptor.GetType()] + else: + raise ValueError('geom_type works only for edges and faces...') - the setter is implemented in the concrete classes + def set_display(self, display): + if hasattr(display, 'DisplayShape'): + self.display_set = True + self.display = display + else: + raise ValueError('not a display') - ''' - if self.is_dirty: - self.build() - return self._topods + def check(self): + """ + """ + + _check = dict(vertex=BRepCheck_Vertex, edge=BRepCheck_Edge, wire=BRepCheck_Wire, face=BRepCheck_Face, + shell=BRepCheck_Shell, solid=BRepCheck_Solid) + _test = _check[self.topo_type] + # TODO: BRepCheck will be able to inform *what* actually is the matter, + # though implementing this still is a bit of work... + raise NotImplementedError - @topo.setter - def topo(self, topods): - assert not type(topods) == None, 'you forgot to set a TopoDS_* type in the __init__ of your concrete class' - assert type(topods) == self._topo_type, 'expected a shell, got {0}'.format(topods) - self._topods = topods + + def is_valid(self): + analyse = BRepCheck_Analyzer(self) + ok = analyse.IsValid() + if ok: + return True + else: + return False def copy(self): """ :return: """ - from OCC.BRepBuilderAPI import BRepBuilderAPI_Copy - cp = BRepBuilderAPI_Copy(self.topo) - cp.Perform(self.topo) - return ShapeToTopology()(cp.Shape()) + cp = BRepBuilderAPI_Copy(self) + cp.Perform(self) + # get the class, construct a new instance + # cast the cp.Shape() to its specific TopoDS topology + _copy = self.__class__( shape_lut(cp.Shape()) ) + return _copy def distance(self, other): ''' @@ -132,10 +137,7 @@ def distance(self, other): minimum distance points on shp1 minimum distance points on shp2 ''' - if isinstance(other, KbeObject): - return minimum_distance(self.topo, other.topo) - else: - return minimum_distance(self.topo, other) + return minimum_distance(self, other) def show( self, *args, **kwargs): """ @@ -143,31 +145,41 @@ def show( self, *args, **kwargs): :param update: redraw the scene or not """ - Display()(self.topo, *args, **kwargs) + if not self.display_set: + Display()(self, *args, **kwargs) + else: + self.disp.DisplayShape(*args, **kwargs) def build(self): if self.name.startswith('Vertex'): - self.topo = make_vertex(self) + self = make_vertex(self) def __eq__(self, other): - return self.topo.IsEqual(other) + return self.IsEqual(other) + + def __ne__(self, other): + return not(self.__eq__(other)) + class GlobalProperties(object): ''' global properties for all topologies ''' def __init__(self, instance): - from OCC.GProp import GProp_GProps - from OCC.BRepGProp import BRepGProp self.instance = instance - self.system = GProp_GProps() - _topo_type = self.instance.type + + @property + def system(self): + self._system = GProp_GProps() + # todo, type should be abstracted with TopoDS... + _topo_type = self.instance.topo_type if _topo_type == 'face' or _topo_type == 'shell': - BRepGProp().SurfaceProperties(self.instance.topo, self.system) + BRepGProp().SurfaceProperties(self.instance, self._system) elif _topo_type == 'edge': - BRepGProp().LinearProperties(self.instance.topo, self.system) + BRepGProp().LinearProperties(self.instance, self._system) elif _topo_type == 'solid': - BRepGProp().VolumeProperties(self.instance.topo, self.system) + BRepGProp().VolumeProperties(self.instance, self._system) + return self._system def centre(self): """ @@ -187,4 +199,15 @@ def bbox(self): ''' returns the bounding box of the face ''' - return get_boundingbox(self.instance.topo) + return get_boundingbox(self.instance) + + def oriented_bbox(self): + """ + return the minimal bounding box + + has dependencies with scipy.spatial + [ has an implementation at hb-robo-code ] + """ + pass + + diff --git a/src/addons/KBE/edge.py b/src/addons/KBE/edge.py index 9fd7b3db7..3e1412ce0 100644 --- a/src/addons/KBE/edge.py +++ b/src/addons/KBE/edge.py @@ -1,39 +1,58 @@ -import warnings from OCC.BRep import BRep_Tool -from OCC.BRepAdaptor import BRepAdaptor_Curve -from OCC.GCPnts import GCPnts_AbscissaPoint, GCPnts_UniformAbscissa -from OCC.Geom import Geom_OffsetCurve, Geom_Curve, Geom_TrimmedCurve +from OCC.BRepAdaptor import BRepAdaptor_Curve, BRepAdaptor_HCurve +from OCC.GCPnts import GCPnts_UniformAbscissa +from OCC.Geom import Geom_OffsetCurve, Geom_TrimmedCurve from OCC.KBE.base import KbeObject from OCC.TopExp import TopExp -from OCC.TopoDS import TopoDS_Wire, TopoDS_Edge, TopoDS_Face, TopoDS_Vertex -from OCC.GeomLib import GeomLib +from OCC.TopoDS import TopoDS_Edge, TopoDS_Vertex, TopoDS_Face from OCC.gp import * # high-level -from OCC.Utils.Common import vertex2pnt, minimum_distance, to_adaptor_3d -from OCC.Utils.Construct import make_edge, trim_wire, fix_continuity +from OCC.Utils.Common import vertex2pnt, minimum_distance +from OCC.Utils.Construct import make_edge, fix_continuity from OCC.Utils.Context import assert_isdone from OCC.KBE.vertex import Vertex - +from OCC.KBE.types_lut import geom_lut +from OCC.GeomLProp import GeomLProp_CurveTool +from OCC.BRepLProp import BRepLProp_CLProps +from OCC.GeomLib import GeomLib +from OCC.GCPnts import GCPnts_AbscissaPoint +from OCC.GeomAPI import GeomAPI_ProjectPointOnCurve +from OCC.ShapeAnalysis import ShapeAnalysis_Edge +from OCC.BRep import * class IntersectCurve(object): - def __init__(self, Instance): - self.Instance = Instance + def __init__(self, instance): + self.instance = instance - def intersect(self, other): - '''intersect self with a point, curve, edge, face, solid + def intersect(self, other, disp, tolerance=1e-2): + '''Intersect self with a point, curve, edge, face, solid method wraps dealing with the various topologies ''' - raise NotImplementedError + if isinstance(other, TopoDS_Face): + from OCC.BRepIntCurveSurface import BRepIntCurveSurface_Inter + face_curve_intersect = BRepIntCurveSurface_Inter() + face_curve_intersect.Init( other, self.instance.adaptor.Curve(), tolerance ) + pnts = [] + while face_curve_intersect.More(): + face_curve_intersect.Next() + pnts.append(face_curve_intersect.Pnt()) + return pnts + + class DiffGeomCurve(object): def __init__(self, instance): self.instance = instance - from OCC.BRepLProp import BRepLProp_CLProps + #self._local_props = BRepLProp_CLProps(self.instance.adaptor, self.instance.degree(), self.instance.tolerance) + self._local_props = BRepLProp_CLProps(self.instance.adaptor, 2, self.instance.tolerance) # initialize with random parameter: 0 - self._curvature = BRepLProp_CLProps(self.instance.adaptor, 0, 2, self.instance.tolerance) - def curvature(self, u, n, resolution=1e-7): + @property + def _curvature(self): + return self._local_props + + def curvature(self, u): self._curvature.SetParameter(u) def radius(self, u): @@ -46,7 +65,7 @@ def radius(self, u): return pnt def curvature(self, u): - # TODO: find a better way to achieve this method + # UGLYYYYYYYYYYYY self._curvature.SetParameter(u) return self._curvature.Curvature() @@ -56,14 +75,18 @@ def tangent(self, u ): ''' self._curvature.SetParameter(u) if self._curvature.IsTangentDefined(): - direction = gp_Dir() - self._curvature.Tangent(direction) + ddd = gp_Dir() + self._curvature.Tangent(ddd) return ddd else: raise ValueError('no tangent defined') def normal(self, u): '''returns the normal at u + + computes the main normal if no normal is found + see: + www.opencascade.org/org/forum/thread_645+&cd=10&hl=nl&ct=clnk&gl=nl ''' try: self._curvature.SetParameter(u) @@ -71,6 +94,24 @@ def normal(self, u): self._curvature.Normal(ddd) return ddd except: +# gp_Vec d1u, d2u; + +# Handle_Geom_Curve aCurv=aCertainCurve; +# +# Standard_Real u=aCertainValue; +# +# // get 1st and 2nd derivative in u +# +# aCurv->D2(u, aPnt, d1u, d2u); +# +# Standard_Real nu_dot = d1u.Dot(d2u)/d1u.Magnitude(); +# +# gp_Vec t_vec = d1u.Divided(d1u.Magnitude()); +# +# // compute the main normal (not the bi normal) +# +# gp_Vec mainn = d2u-(nu_dot*t_vec); + raise ValueError('no normal was found') def derivative(self, u, n): @@ -88,18 +129,17 @@ def derivative(self, u, n): raise AssertionError, 'n of derivative is one of [1,2,3]' def points_from_tangential_deflection(self): - from OCC.GCPnts import GCPnts_TangentialDeflection pass #=============================================================================== -# Curve.construct +# Curve.Construct #=============================================================================== class ConstructFromCurve(): def __init__(self, instance): - self.Instance = instance + self.instance = instance def make_face(self): '''returns a brep face iff self.closed() @@ -118,10 +158,9 @@ def approximate_on_surface(self): ''' approximation of a curve on surface ''' - from OCC.Approx import Approx_CurveOnSurface - raise NotImplementedError + pass -class Edge(KbeObject): +class Edge(KbeObject, TopoDS_Edge): ''' ''' @@ -130,35 +169,56 @@ def __init__(self, edge): ''' assert isinstance(edge, TopoDS_Edge), 'need a TopoDS_Edge, got a %s'% edge.__class__ KbeObject.__init__(self, 'edge') - self._topo_type = TopoDS_Edge - self.topo = edge + TopoDS_Edge.__init__(self, edge) - # STATE; whether cooperative classes are initialized + # tracking state self._local_properties_init = False self._curvature_init = False self._geometry_lookup_init = False self._curve_handle = None self._curve = None self._adaptor = None + self._adaptor_handle = None # instantiating cooperative classes - self.diff_geom = DiffGeomCurve(self) - self.intersect = IntersectCurve(self) - self.construct = ConstructFromCurve(self) + # cooperative classes are distinct through CamelCaps from normal method -> pep8 + self.DiffGeom = DiffGeomCurve(self) + self.Intersect = IntersectCurve(self) + self.Construct = ConstructFromCurve(self) #self.graphic = GraphicCurve(self) # GeomLProp object self._curvature = None - self._local_properties() + #self._local_properties() # some aliasing of useful methods - self.is_closed = self.adaptor.IsClosed - self.is_periodic = self.adaptor.IsPeriodic - self.is_rational = self.adaptor.IsRational - self.continuity = self.adaptor.Continuity - self.degree = self.adaptor.Degree - self.nb_knots = self.adaptor.NbKnots - self.nb_poles = self.adaptor.NbPoles + + def is_closed(self): + return self.adaptor.IsClosed() + + def is_periodic(self): + return self.adaptor.IsPeriodic() + + def is_rational(self): + return self.adaptor.IsRational() + + def continuity(self): + return self.adaptor.Continuity + + def degree(self): + if 'line' in self.type: + return 1 + elif 'curve' in self.type: + return self.adaptor.Degree() + else: + # hyperbola, parabola, circle + return 2 + + def nb_knots(self): + return self.adaptor.NbKnots() + + def nb_poles(self): + return self.adaptor.NbPoles() @property @@ -166,7 +226,7 @@ def curve(self): if self._curve is not None and not self.is_dirty: pass else: - self._curve_handle = BRep_Tool().Curve(self.topo)[0] + self._curve_handle = BRep_Tool().Curve(self)[0] self._curve = self._curve_handle.GetObject() return self._curve @@ -183,11 +243,42 @@ def adaptor(self): if self._adaptor is not None and not self.is_dirty: pass else: - self._adaptor = BRepAdaptor_Curve(self.topo) + self._adaptor = BRepAdaptor_Curve(self) + self._adaptor_handle = BRepAdaptor_HCurve(self._adaptor) return self._adaptor + @property + def adaptor_handle(self): + if self._adaptor_handle is not None and not self.is_dirty: + pass + else: + self.adaptor + return self._adaptor_handle + + @property + def geom_curve_handle(self): + """ + :return: Handle_Geom_Curve adapted from `self` + """ + if self._adaptor_handle is not None and not self.is_dirty: + pass + else: + self.adaptor + return self._adaptor.Curve().Curve() + + @property + def type(self): + return geom_lut[self.adaptor.Curve().GetType()] + + def pcurve(self, face): + """ + computes the 2d parametric spline that lies on the surface of the face + :return: Geom2d_Curve, u, v + """ + crv, u,v = BRep_Tool().CurveOnSurface(self, face) + return crv.GetObject(), u, v + def _local_properties(self): - from OCC.GeomLProp import GeomLProp_CurveTool self._lprops_curve_tool = GeomLProp_CurveTool() self._local_properties_init = True @@ -230,6 +321,10 @@ def trim(self, lbound, ubound, periodic=False): @param lbound: @param ubound: ''' +# if self.is_periodic: +# pass +# else: +# warnings.warn('the wire to be trimmed is not closed, hence cannot be made periodic') a,b = sorted([lbound,ubound]) tr = Geom_TrimmedCurve(self.adaptor.Curve().Curve(), a,b).GetHandle() return Edge(make_edge(tr)) @@ -253,13 +348,12 @@ def extend_by_point(self, pnt, degree=3, beginning=True): def closest(self, other): return minimum_distance(self.brep, other) - def project_pnt_on_edge(self, pnt_or_vertex): + def project_vertex(self, pnt_or_vertex): ''' returns the closest orthogonal project on `pnt` on edge ''' if isinstance(pnt_or_vertex, TopoDS_Vertex): - pnt = vertex2pnt(pnt_or_vertex) + pnt_or_vertex = vertex2pnt(pnt_or_vertex) - from OCC.GeomAPI import GeomAPI_ProjectPointOnCurve poc = GeomAPI_ProjectPointOnCurve(pnt_or_vertex, self.curve_handle) return poc.LowerDistanceParameter(), poc.NearestPoint() @@ -268,15 +362,17 @@ def distance_on_curve(self, distance, close_parameter, estimate_parameter, check on the curve with a distance length from u raises OutOfBoundary if no such parameter exists ''' - from OCC.GCPnts import GCPnts_AbscissaPoint ccc = GCPnts_AbscissaPoint(self.adaptor, distance, close_parameter, estimate_parameter, 1e-5) with assert_isdone(ccc, 'couldnt compute distance on curve'): return ccc.Parameter() def mid_point(self): + """ + :return: the parameter at the mid point of the curve, and its corresponding gp_Pnt + """ _min, _max = self.domain() _mid = (_min+_max) / 2. - return self.adaptor.Value(_mid) + return _mid, self.adaptor.Value(_mid) def divide_by_number_of_points(self, n_pts, lbound=None, ubound=None): '''returns a nested list of parameters and points on the edge @@ -287,7 +383,16 @@ def divide_by_number_of_points(self, n_pts, lbound=None, ubound=None): _lbound = lbound elif ubound: _ubound = ubound - npts = GCPnts_UniformAbscissa(self.adaptor, n_pts, _lbound, _ubound) + + + # minimally two points or a Standard_ConstructionError is raised + if n_pts <= 1: + n_pts = 2 + + try: + npts = GCPnts_UniformAbscissa(self.adaptor, n_pts, _lbound, _ubound) + except: + import ipdb; ipdb.set_trace() if npts.IsDone(): tmp = [] for i in xrange(1,npts.NbPoints()+1): @@ -298,6 +403,7 @@ def divide_by_number_of_points(self, n_pts, lbound=None, ubound=None): else: return None + @property def color(self, indx=None): '''sets or gets the color of self, possible also on a specified controlPoint index @@ -321,34 +427,62 @@ def greville_points(self): '''descriptor setting or getting the coordinate of a control point at indx''' raise NotImplementedError + +# @property +# def periodic(self): +# return self.adaptor.IsPeriodic() +# +# @periodic.setter +# def periodic(self, _bool): +# _bool = bool(_bool) +# if self.is_closed: +# self.adaptor.BSpline() +# else: +# raise warnings.warn('cannot set periodicity on a non-closed edge') + def control_point(self, indx, pt=None): '''gets or sets the coordinate of the control point ''' raise NotImplementedError def __eq__(self, other): - return self.brep.IsEqual(other) - - @property - def type(self): - '''returns edge, wire, curve - determines whether the curve is part of a topology - ''' - return 'edge' + if hasattr(other, 'topo'): + return self.IsEqual(other) + else: + return self.IsEqual(other) - def kind(self): - if not self._geometry_lookup_init: - self._geometry_lookup = GeometryTypeLookup() - self._geometry_lookup_init = True - return self._geometry_lookup[self.curve] + def __ne__(self, other): + return not(self.__eq__(other)) +# def __cmp__(self, other): +# return self.__eq__(other) +# def __contains__(self, item): +# print 'in list?' +# import ipdb; ipdb.set_trace() +# return 0 +# +# def first_vertex(self): # TODO: should return Vertex, not TopoDS_Vertex - return TopExp.FirstVertex(self.topo) + return TopExp.FirstVertex(self) def last_vertex(self): - return TopExp.LastVertex(self.topo) + return TopExp.LastVertex(self) + + def common_vertex(self, edge): + vert = TopoDS_Vertex() + if TopExp.CommonVertex(self, edge, vert): + return vert + else: + return False + + def as_vec(self): + if self.is_line(): + first, last = map( vertex2pnt, [self.first_vertex(), self.last_vertex()] ) + return gp_Vec(first, last) + else: + raise ValueError("edge is not a line, hence no meaningful vector can be returned") #=============================================================================== # Curve. @@ -357,7 +491,7 @@ def last_vertex(self): def parameter_to_point(self, u): '''returns the coordinate at parameter u ''' - return Vertex(*self.adaptor.Value(u).Coord()) + return self.adaptor.Value(u) def point_to_parameter(self, coord): '''returns the parameters / pnt on edge at world coordinate `coord` @@ -374,13 +508,16 @@ def fix_continuity(self, continuity): splits an edge to achieve a level of continuity :param continuity: GeomAbs_C* """ - return fix_continuity(self.topo, continuity) + return fix_continuity(self, continuity) def continuity_to_another_curve(self, other): '''returns continuity between self and another curve ''' return self._lprops_curve_tool(self.curve) + def continuity_from_faces(self, f1, f2): + return BRep_Tool_Continuity(self, f1, f2) + #=============================================================================== # Curve.loop #=============================================================================== @@ -398,27 +535,41 @@ def iter_weights(self): #=============================================================================== # Curve. #=============================================================================== + def is_trimmed(self): + '''checks if curve is trimmed + + check if the underlying geom type is trimmed - def is_planar(self, tolerance=None): - '''checks if the curve is planar within a tolerance ''' raise NotImplementedError - def on_surface(self, surface): + + def is_line(self, tolerance=None): + '''checks if the curve is planar within a tolerance + ''' + if self.nb_knots() == 2 and self.nb_poles() ==2: + return True + else: + return False + + def is_seam(self, face): + """ + :return: True if the edge has two pcurves on one surface + ( in the case of a sphere for example... ) + """ + sae = ShapeAnalysis_Edge() + return sae.IsSeam(self, face) + + def is_edge_on_face(self, face): '''checks whether curve lies on a surface or a face ''' - raise NotImplementedError + return ShapeAnalysis_Edge().HasPCurve(self, face) def on_edge(self, edge): '''checks if the curve lies on an edge or a border ''' raise NotImplementedError - def is_trimmed(self): - '''checks if curve is trimmed - ''' - raise NotImplementedError - #=============================================================================== # Curve.graphic @@ -431,9 +582,9 @@ def show(self, poles=False, vertices=False, knots=False): http://www.opencascade.org/org/forum/thread_1125/ ''' - show = super(self, Edge).show() - if not poles and not vertices and not knots: - show() + show = super(Edge, self).show() + #if not poles and not vertices and not knots: + # show() def update(self, context): '''updates the graphic presentation when called diff --git a/src/addons/KBE/face.py b/src/addons/KBE/face.py index cd2ca3506..11ba33fa2 100644 --- a/src/addons/KBE/face.py +++ b/src/addons/KBE/face.py @@ -15,10 +15,19 @@ #=============================================================================== from OCC.KBE.base import Display, KbeObject, GlobalProperties from OCC.KBE.edge import Edge -from OCC.Utils.Construct import gp_Vec, gp_Pnt, gp_Dir, gp_Pnt2d -from OCC.Utils.Topology import Topo +from OCC.Utils.Construct import * from OCC.BRep import BRep_Tool from OCC.TopoDS import * +from OCC.GeomLProp import GeomLProp_SLProps +from OCC.BRepCheck import BRepCheck_Face +from OCC.BRepTools import BRepTools, BRepTools_UVBounds +from OCC.BRepAdaptor import BRepAdaptor_Surface, BRepAdaptor_HSurface +from OCC.ShapeAnalysis import ShapeAnalysis_Surface +from OCC.IntTools import IntTools_FaceFace +from OCC.ShapeAnalysis import ShapeAnalysis_Surface +from OCC.GeomProjLib import GeomProjLib +from OCC.Utils.Topology import Topo, WireExplorer + ''' @@ -53,11 +62,31 @@ def curvature(self, u,v): curvatureType ''' if not self._curvature_initiated: - from OCC.GeomLProp import GeomLProp_SLProps - self._curvature = GeomLProp_SLProps(self.instance.h_srf, u, v, 1, 1e-6) - else: - self._curvature.SetParameters(u,v) - self._curvature_initiated = True + self._curvature = GeomLProp_SLProps(self.instance.surface_handle, u, v, 1, 1e-6) + + _domain = self.instance.domain() + if u in _domain or v in _domain: + print '<<>>' + div = 1000 + delta_u, delta_v = (_domain[0] - _domain[1])/div, (_domain[2] - _domain[3])/div + + if u in _domain: + low, hi = u-_domain[0], u-_domain[1] + if low < hi: + u = u - delta_u + else: + u = u + delta_u + + if v in _domain: + low, hi = v-_domain[2], v-_domain[3] + if low < hi: + v = v - delta_v + else: + v = v + delta_v + + + self._curvature.SetParameters(u,v) + self._curvature_initiated = True return self._curvature @@ -81,38 +110,14 @@ def normal(self,u,v): else: raise ValueError('normal is not defined at u,v: {0}, {1}'.format(u,v)) - def tangent(self,u,v, recurse=False): + def tangent(self,u,v): dU, dV = gp_Dir(), gp_Dir() curv = self.curvature(u,v) - if curv.IsCurvatureDefined(): + if curv.IsTangentUDefined() and curv.IsTangentVDefined(): curv.TangentU(dU), curv.TangentV(dV) return dU, dV else: - # most likely the curvature is just out of bounds... - # move it a little close to the center of the surface... - tol = 1e-2 - - print 'trying to fix shit...' - - domain = self.instance.domain() - if u in domain: - uorv = 'u' - elif v in domain: - uorv = 'v' - else: - raise ValueError('no curvature defined while sample does not lie on border...') - - if uorv is not None: - indx = domain.index(u) if uorv == 'u' else domain.index(v) - if indx in (1,3): # v - v = v + tol if indx == 1 else v - tol - else: - u = u + tol if indx == 0 else u - tol - print 'hopefully fixed it?' - if not recurse: - self.tangent(u,v, True) - else: - return None + return None, None def radius(self, u, v ): '''returns the radius at u @@ -166,39 +171,6 @@ def inflection_parameters(self): pass -#=============================================================================== -# Surface.dress_up -#=============================================================================== - -class DressUpSurface(object): - def __init__(self, instance): - self.instance = instance - - def fillet_vertex_distance(self, vertex, distance): - '''fillets 3 edges at a corner - ''' - pass - - def fillet_edge_radius(self, edge, radius): - '''fillets an edge - ''' - pass - - def chamfer_vertex_distance(self, vertex, distance): - '''chamfer 3 edges at a corner - ''' - pass - - def chamfer_edge_angle(self, edge, angle): - '''chamfers the faces on edge at angle - ''' - pass - - def chamfer_edge_distance_distance(self, edge, distance_this_face, distance_other_face): - '''chamfers the face incident on edge at a given distance - ''' - pass - #=============================================================================== # Surface.intersect #=============================================================================== @@ -223,7 +195,7 @@ def intersect_curve(self, crv): return uvw, bics.Point(), bics.Face(), bics.Transition() -class Face(KbeObject): +class Face(KbeObject, TopoDS_Face): """high level surface API object is a Face iff part of a Solid otherwise the same methods do apply, apart from the topology obviously @@ -231,67 +203,93 @@ class Face(KbeObject): def __init__(self, face): ''' ''' - from OCC.TopoDS import TopoDS_Face KbeObject.__init__(self, name='face') - self._topo_type = TopoDS_Face - self.topo = face - + TopoDS_Face.__init__(self, face) # cooperative classes - self.GlobalProperties = GlobalProperties(self) self.DiffGeom = DiffGeomSurface(self) # STATE; whether cooperative classes are yet initialized self._curvature_initiated = False self._geometry_lookup_init = False + #=============================================================================== + # properties + #=============================================================================== self._h_srf = None self._srf = None self._adaptor = None self._adaptor_handle = None self._classify_uv = None # cache the u,v classifier, no need to rebuild for every sample + self._topo = None # aliasing of useful methods - self.is_u_periodic = self.adaptor.IsUPeriodic - self.is_v_periodic = self.adaptor.IsVPeriodic - self.is_u_closed = self.adaptor.IsUClosed - self.is_v_closed = self.adaptor.IsVClosed - self.is_u_rational = self.adaptor.IsURational - self.is_u_rational = self.adaptor.IsVRational - self.u_degree = self.adaptor.UDegree - self.v_degree = self.adaptor.VDegree - self.u_continuity = self.adaptor.UContinuity - self.v_continuity = self.adaptor.VContinuity - - # meh, RuntimeError... - self.nb_u_knots = self.adaptor.NbUKnots - self.nb_v_knots = self.adaptor.NbVKnots - self.nb_u_poles = self.adaptor.NbUPoles - self.nb_v_poles = self.adaptor.NbVPoles - - def show(self, *args, **kwargs): - # TODO: factor out once inheriting from KbeObject - Display()(self.topo, *args, **kwargs) - - def check(self): - ''' - interesting for valdating the state of self - ''' - from OCC.BRepCheck import BRepCheck_Face - bcf = BRepCheck_Face(self.topo) - return bcf + def is_u_periodic(self): + return self.adaptor.IsUPeriodic() + + def is_v_periodic(self): + return self.adaptor.IsVPeriodic() + + def is_u_closed(self): + return self.adaptor.IsUClosed() + + def is_v_closed(self): + return self.adaptor.IsVClosed() + + def is_u_rational(self): + return self.adaptor.IsURational() + + def is_u_rational(self): + return self.adaptor.IsVRational() + + def u_degree(self): + return self.adaptor.UDegree() + + def v_degree(self): + return self.adaptor.VDegree() + + def u_continuity(self): + return self.adaptor.UContinuity() + + def v_continuity (self): + return self.adaptor.VContinuity() + + # mehhh RuntimeError... + #def nb_u_knots = self.adaptor.NbUKnots + #def nb_v_knots = self.adaptor.NbVKnots + #def nb_u_poles = self.adaptor.NbUPoles + #def nb_v_poles = self.adaptor.NbVPoles def domain(self): - '''returns the u,v domain of the curve''' - from OCC.BRepTools import BRepTools - return BRepTools.UVBounds(self.topo) + '''the u,v domain of the curve + :return: UMin, UMax, VMin, VMax + ''' + return BRepTools.UVBounds(self) + + def mid_point(self): + """ + :return: the parameter at the mid point of the face, and its corresponding gp_Pnt + """ + u_min, u_max, v_min, v_max = self.domain() + u_mid = (u_min + u_max) / 2. + v_mid = (v_min + v_max) / 2. + pnt = self.parameter_to_point(u_mid, v_mid) + return ( (u_mid, v_mid), self.adaptor.Value(u_mid, v_mid) ) + + @property + def topo(self): + if self._topo is not None: + return self._topo + else: + self._topo = Topo(self) + return self._topo @property def surface(self): if self._srf is not None and not self.is_dirty: pass else: - self._h_srf = BRep_Tool_Surface(self.topo) + self._h_srf = BRep_Tool_Surface(self) self._srf = self._h_srf.GetObject() return self._srf @@ -308,8 +306,7 @@ def adaptor(self): if self._adaptor is not None and not self.is_dirty: pass else: - from OCC.BRepAdaptor import BRepAdaptor_Surface, BRepAdaptor_HSurface - self._adaptor = BRepAdaptor_Surface(self.topo) + self._adaptor = BRepAdaptor_Surface(self) self._adaptor_handle = BRepAdaptor_HSurface() self._adaptor_handle.Set(self._adaptor) return self._adaptor @@ -335,37 +332,44 @@ def close(self): '''if possible, close self''' raise NotImplementedError - @property - def type(self): - return 'face' - - def kind(self): - if not self._geometry_lookup_init: - self._geometry_lookup = GeometryTypeLookup() - self._geometry_lookup_init = True - return self._geometry_lookup[self.topo] - def is_closed(self): - from OCC.ShapeAnalysis import ShapeAnalysis_Surface sa = ShapeAnalysis_Surface(self.surface_handle) - sa.GetBoxUF() + # sa.GetBoxUF() return sa.IsUClosed(), sa.IsVClosed() - def is_planar(self): + def is_planar(self, tol=TOLERANCE): '''checks if the surface is planar within a tolerance :return: bool, gp_Pln ''' - aaa = GeomLib_IsPlanarSurface(self.surface_handle, self.tolerance) - if aaa.IsPlanar(): - return aaa.IsPlanar(), aaa.Plan() - else: - return aaa.IsPlanar(), None + aaa = GeomLib_IsPlanarSurface(self.surface_handle, tol) + return aaa.IsPlanar()# , aaa.Plan() + + def is_trimmed(self): + """ + :return: True if the Wire delimiting the Face lies on the bounds of the surface + if this is not the case, the wire represents a contour that delimits the face [ think cookie cutter ] + and implies that the surface is trimmed + """ + #if not(BRep_Tool().NaturalRestriction(self)): + # return True + _round = lambda x: round(x,3) + a = map(_round, BRepTools_UVBounds(self)) + b = map(_round, self.adaptor.Surface().Surface().GetObject().Bounds()) + if a != b: + print 'a,b',a,b + return True + return False + + def is_overlapping(self, other): + import ipdb; ipdb.set_trace() + overlap = IntTools_FaceFace() + def on_trimmed(self, u, v): '''tests whether the surface at the u,v parameter has been trimmed ''' if self._classify_uv is None: - self._classify_uv = BRepTopAdaptor_FClass2d(self.topo, 1e-9) + self._classify_uv = BRepTopAdaptor_FClass2d(self, 1e-9) uv = gp_Pnt2d(u,v) if self._classify_uv.Perform(uv) == TopAbs_IN: return True @@ -382,7 +386,6 @@ def point_to_parameter(self, pt): returns the uv value of a point on a surface @param pt: ''' - from OCC.ShapeAnalysis import ShapeAnalysis_Surface sas = ShapeAnalysis_Surface(self.surface_handle) uv = sas.ValueOfUV(pt, self.tolerance) return uv.Coord() @@ -401,11 +404,9 @@ def continuity_edge_face(self, edge, face): :return: bool, GeomAbs_Shape if it has continuity, otherwise False, None """ - edge = edge if not isinstance(edge,KbeObject) else edge.topo - face = face if not isinstance(face, KbeObject) else face.topo bt = BRep_Tool() - if bt.HasContinuity(edge, self.topo, face): - continuity = bt.Continuity(edge, self.topo, face) + if bt.HasContinuity(edge, self, face): + continuity = bt.Continuity(edge, self, face) return True, continuity else: return False, None @@ -415,7 +416,7 @@ def continuity_edge_face(self, edge, face): # project curve, point on face #=============================================================================== - def project_vertex( self, other ): + def project_vertex( self, pnt, tol=TOLERANCE): '''projects self with a point, curve, edge, face, solid method wraps dealing with the various topologies @@ -423,21 +424,20 @@ def project_vertex( self, other ): returns uv, point ''' - if isinstance(other, TopoDS_Face): - raise AssertionError, 'Cannot project a face on another face' - - elif isinstance(other, TopoDS_Vertex): - pt = BRep_Tool.Pnt(other) - proj = GeomAPI_ProjectPointOnSurf(pt, self.surface_handle) - # SHOULD USE THIS!!! - #proj.LowerDistanceParameters() - ext = proj.Extrema() - for i in range(ext.NbExt()): - if proj.Point().Coord() == ext.Point(i).Value().Coord(): - result = ext.Point(i) - uv = result.Parameter() - pt = result.Value() - return uv, pt + if isinstance(pnt, TopoDS_Vertex): + pnt = BRep_Tool.Pnt(pnt) + + #print "from OCC.ShapeAnalysis import ShapeAnalysis_Surface" +# from OCC.ShapeAnalysis import ShapeAnalysis_Surface +# +# ssa = ShapeAnalysis_Surface(self.surface_handle) +# ssa.NextValueOfUV() + + proj = GeomAPI_ProjectPointOnSurf(pnt, self.surface_handle, tol) + uv = proj.LowerDistanceParameters() + proj_pnt = proj.NearestPoint() + + return uv, proj_pnt def project_curve(self, other): # this way Geom_Circle and alike are valid too @@ -447,25 +447,45 @@ def project_curve(self, other): if isinstance(other, TopoDS_Edge): # convert edge to curve first, last = TopExp.FirstVertex(other), TopExp.LastVertex(other) - lbound, ubound = BRep_Tool().Parameter(first, other), BRep_Tool().Parameter(first, other) + lbound, ubound = BRep_Tool().Parameter(first, other), BRep_Tool().Parameter(last, other) other = BRep_Tool.Curve(other, lbound, ubound).GetObject() - from OCC.GeomProjLib import GeomProjLib return GeomProjLib().Project(other, self.surface_handle) def project_edge(self, edg): - return self.project_cur + if hasattr(edg, 'adaptor'): + return self.project_curve(self, self.adaptor) + return self.project_curve(self, to_adaptor_3d(edg)) + +# def iso_curve(self, u_or_v, param): +# """ +# :return: an iso curve at parameter `param` +# :param u_or_v: "u" or "v" +# :param param: the parameter where the iso curve lies +# """ +# pass def iso_curve(self, u_or_v, param): """ - :return: an iso curve at parameter `param` - :param u_or_v: "u" or "v" - :param param: the parameter where the iso curve lies + get the iso curve from a u,v + parameter + :param u_or_v: + :param param: + :return: """ - pass + from OCC.Adaptor3d import Adaptor3d_IsoCurve + uv = 0 if u_or_v == 'u' else 1 + # TODO: REFACTOR, part of the Face class now... + iso = Adaptor3d_IsoCurve(self.adaptor_handle.GetHandle(), uv, param) + return iso def Edges(self): - return [Edge(i) for i in Topo(self.topo).edges()] + return [Edge(i) for i in WireExplorer(self.topo.wires().next()).ordered_edges()] + + def __repr__(self): + return self.name + + def __str__(self): + return self.__repr__() if __name__ == "__main__": diff --git a/src/addons/KBE/plane.py b/src/addons/KBE/plane.py new file mode 100644 index 000000000..b317c46ef --- /dev/null +++ b/src/addons/KBE/plane.py @@ -0,0 +1,42 @@ +from OCC.Geom import Geom_Plane +from OCC.GeomAPI import GeomAPI_IntCS, GeomAPI_IntSS +from OCC.gp import gp_Pln + +IntAna_Quadric # gp_* / gp_* intersect +IntAna_QuadQuadGeo +Extrema_ExtPElC + +class Plane(object): # HalfSpace + def __init__(self, pln): + + self.pln = None + self.geom_plane = None # property + + if isinstance(pln, gp_Pln.__class__) + self.pln = pln + elif isinstance(pln, Geom_Plane): + self.pln = pln.Pln() + self.geom_plane = pln + + def intersect_curve(): + """ + any line! + """ + GeomAPI_IntCS + + def intersect_surface(): + GeomAPI_IntSS + + def intersect_plane_plane(pln, pln): + pass + + def project_curve(): + pass + + def project_surface(): + pass + + + + + diff --git a/src/addons/KBE/scratchpad.py b/src/addons/KBE/scratchpad.py new file mode 100644 index 000000000..41ab1baa8 --- /dev/null +++ b/src/addons/KBE/scratchpad.py @@ -0,0 +1,5 @@ +__author__ = 'jdf' + +Curve + + \ No newline at end of file diff --git a/src/addons/KBE/shell.py b/src/addons/KBE/shell.py new file mode 100644 index 000000000..909e0dad9 --- /dev/null +++ b/src/addons/KBE/shell.py @@ -0,0 +1,76 @@ +from .base import KbeObject, GlobalProperties +from .face import Face +from .wire import Wire + +from OCC.TopoDS import TopoDS_Shell + +from OCC.Utils.Topology import Topo + + +class DressUp(object): + def __init__(self, instance): + self.instance = instance + + def fillet_vertex_distance(self, vertex, distance): + '''fillets 3 edges at a corner + ''' + pass + + def fillet_edge_radius(self, edge, radius): + '''fillets an edge + ''' + pass + + def chamfer_vertex_distance(self, vertex, distance): + '''chamfer 3 edges at a corner + ''' + pass + + def chamfer_edge_angle(self, edge, angle): + '''chamfers the faces on edge at angle + ''' + pass + + def chamfer_edge_distance_distance(self, edge, distance_this_face, distance_other_face): + '''chamfers the face incident on edge at a given distance + ''' + pass + + +class Shell(KbeObject, TopoDS_Shell): + _n = 0 + def __init__(self, shell): + KbeObject.__init__(self, name='Shell #{0}'.format(self._n)) + TopoDS_Shell.__init__(self, shell) + self.GlobalProperties = GlobalProperties(self) + self.DressUp = DressUp(self) + self._n += 1 + + def analyse(self): + """ + + :return: + """ + from OCC.ShapeAnalysis import ShapeAnalysis_Shell + ss = ShapeAnalysis_Shell(self) + if ss.HasFreeEdges(): + bad_edges = [e for e in Topo(ss.BadEdges()).edges()] + + + def Faces(self): + """ + + :return: + """ + return Topo(self, True).faces() + + def Wires(self): + """ + + :return: + """ + return Topo(self, True).wires() + + def Edges(self): + return Topo(self, True).edges() + diff --git a/src/addons/KBE/solid.py b/src/addons/KBE/solid.py index 341892772..2440920d1 100644 --- a/src/addons/KBE/solid.py +++ b/src/addons/KBE/solid.py @@ -1,60 +1,17 @@ -from .base import KbeObject, GlobalProperties -from .face import Face - -from OCC.TopoDS import TopoDS_Shell - +from OCC.TopoDS import TopoDS_Solid +from base import GlobalProperties, KbeObject +from shell import Shell from OCC.Utils.Topology import Topo -class Shell(KbeObject): - _n = 0 - def __init__(self, shell): - KbeObject.__init__(self, name='Shell #{0}'.format(self._n)) - self._topo_type = TopoDS_Shell - self.topo = shell - self.global_properties = GlobalProperties(self) - self._n += 1 - - - def copy(self): - cp = super(Shell, self).copy() - return Shell(cp) - - @property - def type(self): - return 'shell' - - def analyse(self): - """ - - :return: - """ - from OCC.ShapeAnalysis import ShapeAnalysis_Shell - ss = ShapeAnalysis_Shell(self.topo) - if ss.HasFreeEdges(): - bad_edges = [e for e in Topo(ss.BadEdges()).edges()] - - - def Faces(self): - """ - - :return: - """ - return (Face(f) for f in Topo(self.topo).faces()) - - def Wires(self): - """ - :return: - """ - return (Wire(w) for w in Topo(self.topo)) - +class Solid(KbeObject, TopoDS_Solid): -class Solid(Shell): """high level Solid Api""" def __init__(self, solid): - self._topo_type = TopoDS_Solid - self.topo = solid - self.global_properties = GlobalProperties(self) + KbeObject.__init__(name='solid') + TopoDS_Solid.__init__(self, solid) + self.GlobalProperties = GlobalProperties(self) + self.DressUp = DressUp(self) # def parameter_to_coordinate(self, coord): @@ -79,7 +36,7 @@ def intersect(self, other_solid): ''' def shells(self): - return (Shell(sh) for sh in Topo(self.topo)) + return (Shell(sh) for sh in Topo(self)) #=============================================================================== # Solid.graphic #=============================================================================== diff --git a/src/addons/KBE/types_lut.py b/src/addons/KBE/types_lut.py index 909b8cebd..7d9547dcb 100644 --- a/src/addons/KBE/types_lut.py +++ b/src/addons/KBE/types_lut.py @@ -1,27 +1,10 @@ ''' this class abstract types ''' -from OCC import GeomAbs +from OCC.BRepCheck import * +from OCC.GeomAbs import * from OCC.TopoDS import * from OCC.TopAbs import * -from OCC import TopAbs - -class GeometryLookup(object): - def __init__(self): - self.lookup, self.reverse_lookup = {}, {} - # construct a geometry types / enum dict - for i in dir(GeomAbs): - if i.startswith('GeomAbs_'): - value = GeomAbs.__dict__[i] - self.lookup[i] = value - self.reverse_lookup[value] = i - - def __getitem__(self, check): - try: - return self.reverse_lookup[ check ] - except KeyError: - print 'failed to lookup geometry type' - return None class ShapeToTopology(object): ''' @@ -29,7 +12,8 @@ class ShapeToTopology(object): ''' def __init__(self): self.tds = TopoDS() - self.topoTypes = { TopAbs_VERTEX: self.tds.vertex, + self.topoTypes = { + TopAbs_VERTEX: self.tds.vertex, TopAbs_EDGE: self.tds.edge, TopAbs_FACE: self.tds.face, TopAbs_WIRE: self.tds.wire, @@ -44,150 +28,191 @@ def __call__(self, shape): return self.topoTypes[shape.ShapeType()](shape) else: raise AttributeError('shape has not method `ShapeType`') - + def __getitem__(self, item): + return self(item) -class TopologyLookup(object): - ''' - looks up the topology type of a Adaptor or Topo_DS type and returns a string - ''' - def __init__(self): - # nessecary to filter out stuff like TopAbs_IN which are related to orientation, not Topology - _topoTypesA = ['TopAbs_VERTEX', 'TopAbs_EDGE', 'TopAbs_EDGE', 'TopAbs_WIRE', 'TopAbs_FACE', - 'TopAbs_SHELL','TopAbs_SOLID','TopAbs_COMPSOLID', 'TopAbs_COMPOUND', 'TopAbs_SHAPE' ] - - _topoTypesB = [TopAbs_VERTEX, TopAbs_EDGE, TopAbs_EDGE, TopAbs_WIRE, TopAbs_FACE, - TopAbs_SHELL,TopAbs_SOLID,TopAbs_COMPSOLID, TopAbs_COMPOUND, TopAbs_SHAPE ] - - self.lookup = dict(zip(_topoTypesA, _topoTypesB)) - self.reverse_lookup = {} - for k,v in self.lookup.iteritems(): - self.reverse_lookup[v]=k - - def __getitem__(self, check): - try: - return self.reverse_lookup[ check ] - except KeyError: - print 'failed to lookup geometry type' - return None - - -class OrientationLookup(object): - ''' - looks up the orientation type and returns a string - ''' - def __init__(self): - # nessecary to filter out stuff like TopAbs_IN which are related to orientation, not Topology - _topoTypesA = ['TopAbs_FORWARD', 'TopAbs_REVERSED', 'TopAbs_INTERNAL', 'TopAbs_EXTERNAL' ] - _topoTypesB = [TopAbs_FORWARD, TopAbs_REVERSED, TopAbs_INTERNAL, TopAbs_EXTERNAL ] - - self.lookup = dict(zip(_topoTypesA, _topoTypesB)) - self.reverse_lookup = {} - for k,v in self.lookup.iteritems(): - self.reverse_lookup[v]=k - - def __getitem__(self, check): - try: - return self.reverse_lookup[ check ] - except KeyError: - print 'failed to lookup orientation type' - return None - - -class StateLookup(object): - ''' - looks up the orientation type and returns a string - ''' - - from OCC import TopAbs - def __init__(self): - # nessecary to filter out stuff like TopAbs_IN which are related to orientation, not Topology - _topoTypesA = ['TopAbs_IN', 'TopAbs_OUT', 'TopAbs_ON', 'TopAbs_UNKNOWN' ] - _topoTypesA = [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN ] - - self.lookup = dict(zip(_topoTypesA, _topoTypesB)) - self.reverse_lookup = {} - for k,v in self.lookup.iteritems(): - self.reverse_lookup[v]=k - - def __getitem__(self, check): - try: - return self.reverse_lookup[ check ] - except KeyError: - print 'failed to lookup state type' - return None - - -class StateLookup(object): - ''' - looks up the orientation type and returns a string +#class ClassifyTopology(object): +# ''' +# returns what type `topoType` is +# +# const +# +# @param topoType: +# +# fundamental types to inherit from: +# TopoDS_Shape +# Adaptor3d_Curve +# Adaptor2d_Curve2d +# #gce_root +# +# ''' +# def __init__(self): +# ''' +# constructs a lookup of all (reasonbly) possible geometric OCC types +# ''' +# self.topoTypes = [TopoDS_Vertex,] +# +# self.adaptorTypes =[] +# self.gpTypes = [] +# +# self.topo_lookup = TopologyTypeLookup() +# self.adaptor_lookup = AdaptorTypeLookup() +# self.gp_lookup = GpTypeLookup() +# +# from OCC import TopoDS, gp, Adaptor2d, Adaptor3d +# +# def __getitem__(self, other): +# for i in _possible: +# if isinstance(topoType, i): +# return i +# +# def is_adaptor_curve_type(self, other): +# issubclass(other.__class__, Adaptor2d_Curve2d) or isinstance(other.__class__, Adaptor3d_Curve) +# +# def is_adaptor_surface_type(self, other): +# issubclass(other.__class__, Adaptor3d_Surface) +# +# def is_adaptor_type(self, other): +# return True if self.is_adaptor_curve_type(other) or self.is_adaptor_surface_type(other) else False +# +# def is_topods_type(self, other): +# issubclass(other.__class__, TopoDS_Shape) +# +# def is_gp_type(self, other): +# return True if other.__class__.__name__.split('_')[0] == 'gp' or 'jajaja' else False + +class EnumLookup(object): + """ + perform bi-directional lookup of Enums'... + """ + def __init__(self, li_in, li_out): + self.d = {} + for a,b in zip(li_in, li_out): + self.d[a]=b + self.d[b]=a + + def __getitem__(self, item): + return self.d[item] + + +_curve_typesA = (GeomAbs_Line, GeomAbs_Circle,GeomAbs_Ellipse,GeomAbs_Hyperbola,GeomAbs_Parabola, +GeomAbs_BezierCurve,GeomAbs_BSplineCurve,GeomAbs_OtherCurve) +_curve_typesB = ('line', 'circle', 'ellipse','hyperbola','parabola','bezier','spline','other') + + +_surface_typesA = (GeomAbs_Plane ,GeomAbs_Cylinder, GeomAbs_Cone ,GeomAbs_Sphere, GeomAbs_Torus, +GeomAbs_BezierSurface, GeomAbs_BSplineSurface, GeomAbs_SurfaceOfRevolution, GeomAbs_SurfaceOfExtrusion, +GeomAbs_OffsetSurface, GeomAbs_OtherSurface ) +_surface_typesB = ('plane','cylinder', 'cone', 'sphere', 'torus', 'bezier', 'spline', 'revolution', +'extrusion', 'offset', 'other') + + +_stateA = ('in', 'out', 'on', 'unknown') +_stateB = (TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN) + + +_orientA = ['TopAbs_FORWARD', 'TopAbs_REVERSED', 'TopAbs_INTERNAL', 'TopAbs_EXTERNAL' ] +_orientB = [TopAbs_FORWARD, TopAbs_REVERSED, TopAbs_INTERNAL, TopAbs_EXTERNAL ] + + +_topoTypesA = ['vertex', 'edge', 'wire', 'face', 'shell','solid','compsolid', 'compound', 'shape' ] +_topoTypesB = [ TopAbs_VERTEX, TopAbs_EDGE, TopAbs_WIRE, TopAbs_FACE, TopAbs_SHELL,TopAbs_SOLID, + TopAbs_COMPSOLID, TopAbs_COMPOUND, TopAbs_SHAPE ] + + + +_geom_types_a = ['line', 'circle', 'ellipse', 'hyperbola', 'parabola', 'beziercurve', 'bsplinecurve','othercurve'] +_geom_types_b = [GeomAbs_Line, GeomAbs_Circle, GeomAbs_Ellipse, GeomAbs_Hyperbola, GeomAbs_Parabola, GeomAbs_BezierCurve,\ + GeomAbs_BSplineCurve, GeomAbs_OtherCurve ] + + +# TODO: make a function that generalizes this, there is absolutely no need for 2 lists to define an EnumLookup!!! + +def fix_formatting(_str): + return [i.strip() for i in _str.decode('string_escape').split(',')] + +_brep_check_a = fix_formatting("NoError, InvalidPointOnCurve, InvalidPointOnCurveOnSurface, InvalidPointOnSurface,\ +No3DCurve, Multiple3DCurve, Invalid3DCurve, NoCurveOnSurface,\ +InvalidCurveOnSurface, InvalidCurveOnClosedSurface, InvalidSameRangeFlag, InvalidSameParameterFlag,\ +InvalidDegeneratedFlag, FreeEdge, InvalidMultiConnexity, InvalidRange,\ +EmptyWire, RedundantEdge, SelfIntersectingWire, NoSurface,\ +InvalidWire, RedundantWire, IntersectingWires, InvalidImbricationOfWires,\ +EmptyShell, RedundantFace, UnorientableShape, NotClosed,\ +NotConnected, SubshapeNotInShape, BadOrientation, BadOrientationOfSubshape,\ +InvalidToleranceValue, CheckFail") + +_brep_check_b = [BRepCheck_NoError, BRepCheck_InvalidPointOnCurve, BRepCheck_InvalidPointOnCurveOnSurface, BRepCheck_InvalidPointOnSurface, +BRepCheck_No3DCurve, BRepCheck_Multiple3DCurve, BRepCheck_Invalid3DCurve, BRepCheck_NoCurveOnSurface, +BRepCheck_InvalidCurveOnSurface, BRepCheck_InvalidCurveOnClosedSurface, BRepCheck_InvalidSameRangeFlag, BRepCheck_InvalidSameParameterFlag, +BRepCheck_InvalidDegeneratedFlag, BRepCheck_FreeEdge, BRepCheck_InvalidMultiConnexity, BRepCheck_InvalidRange, +BRepCheck_EmptyWire, BRepCheck_RedundantEdge, BRepCheck_SelfIntersectingWire, BRepCheck_NoSurface, +BRepCheck_InvalidWire, BRepCheck_RedundantWire, BRepCheck_IntersectingWires, BRepCheck_InvalidImbricationOfWires, +BRepCheck_EmptyShell, BRepCheck_RedundantFace, BRepCheck_UnorientableShape, BRepCheck_NotClosed, +BRepCheck_NotConnected, BRepCheck_SubshapeNotInShape, BRepCheck_BadOrientation, BRepCheck_BadOrientationOfSubshape, +BRepCheck_InvalidToleranceValue, BRepCheck_CheckFail] + +brepcheck_lut = EnumLookup( _brep_check_a, _brep_check_b ) +curve_lut = EnumLookup(_curve_typesA,_curve_typesB) +surface_lut = EnumLookup(_surface_typesA, _surface_typesB) +state_lut = EnumLookup(_stateA, _stateB) +orient_lut = EnumLookup(_orientA, _orientB) +topo_lut = EnumLookup(_topoTypesA,_topoTypesB) +shape_lut = ShapeToTopology() +geom_lut= EnumLookup(_geom_types_a, _geom_types_b) + +# todo: refactor, these classes have been moved from the "Topology" directory +# which had too many overlapping methods & classes, that are now part of the KBE module... +# still need to think what to do with these... +# what_is_face should surely become a lut [ geom_lut? ] +# i'm not sure whether casting to a gp_* is useful... + +from OCC.Geom import * +from OCC.TopAbs import * + +classes = dir() +geom_classes = [] +for elem in classes: + if (elem.startswith('Geom') and not 'swig' in elem): + geom_classes.append(elem) + +def what_is_face(face): + ''' Returns all class names for which this class can be downcasted ''' - - from OCC import TopAbs - def __init__(self): - # nessecary to filter out stuff like TopAbs_IN which are related to orientation, not Topology - _topoTypesA = ['TopAbs_IN', 'TopAbs_OUT', 'TopAbs_ON', 'TopAbs_UNKNOWN' ] - _topoTypesA = [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN ] - - self.lookup = dict(zip(_topoTypesA, _topoTypesB)) - self.reverse_lookup = {} - for k,v in self.lookup.iteritems(): - self.reverse_lookup[v]=k - - def __getitem__(self, check): - try: - return self.reverse_lookup[ check ] - except KeyError: - print 'failed to lookup state type' - return None - -class ClassifyTopology(object): + if not face.ShapeType()==TopAbs_FACE: + print '%s is not a TopAbs_FACE. Conversion impossible' + return None + hs = BRep_Tool().Surface(face) + obj = hs.GetObject() + result = [] + for elem in classes: + if (elem.startswith('Geom') and not 'swig' in elem): + geom_classes.append(elem) + # Run the test for each class + for geom_class in geom_classes: + if obj.IsKind(geom_class) and not geom_class in result: + result.append(geom_class) + return result + +def face_is_plane(face): + ''' Returns True if the TopoDS_Shape is a plane, False otherwise ''' - returns what type `topoType` is - - const - - @param topoType: - - fundamental types to inherit from: - TopoDS_Shape - Adaptor3d_Curve - Adaptor2d_Curve2d - #gce_root - + hs = BRep_Tool().Surface(face) + downcast_result = Handle_Geom_Plane().DownCast(hs) + # the handle is null if downcast failed or is not possible, + # that is to say the face is not a plane + if downcast_result.IsNull(): + return False + else: + return True + +def shape_is_cylinder(face): + ''' Returns True is the TopoDS_Shape is a cylinder, False otherwise ''' - def __init__(self): - ''' - constructs a lookup of all (reasonbly) possible geometric OCC types - ''' - self.topoTypes = [TopoDS_Vertex,] - - self.adaptorTypes =[] - self.gpTypes = [] - - self.topo_lookup = TopologyTypeLookup() - self.adaptor_lookup = AdaptorTypeLookup() - self.gp_lookup = GpTypeLookup() - - from OCC import TopoDS, gp, Adaptor2d, Adaptor3d - - def __getitem__(self, other): - for i in _possible: - if isinstance(topoType, i): - return i - - def is_adaptor_curve_type(self, other): - issubclass(other.__class__, Adaptor2d_Curve2d) or isinstance(other.__class__, Adaptor3d_Curve) - - def is_adaptor_surface_type(self, other): - issubclass(other.__class__, Adaptor3d_Surface) - - def is_adaptor_type(self, other): - return True if self.is_adaptor_curve_type(other) or self.is_adaptor_surface_type(other) else False - - def is_topods_type(self, other): - issubclass(other.__class__, TopoDS_Shape) - - def is_gp_type(self, other): - return True if other.__class__.__name__.split('_')[0] == 'gp' or 'jajaja' else False + hs = BRep_Tool().Surface(face) + handle_geom_plane = Handle_Geom_Cylinder().DownCast(hs) + if downcast_result.IsNull(): + return False + else: + return True diff --git a/src/addons/KBE/vertex.py b/src/addons/KBE/vertex.py index 83d49391b..48fb797ad 100644 --- a/src/addons/KBE/vertex.py +++ b/src/addons/KBE/vertex.py @@ -1,22 +1,44 @@ -from OCC.Utils.Common import TOLERANCE, vertex2pnt + +#from OCC.Utils.Construct import make_vertex +from OCC.BRepPrimAPI import * + from OCC.Utils.Construct import make_vertex -from OCC.gp import gp_Pnt + +from OCC.Utils.Common import TOLERANCE, vertex2pnt +from OCC.gp import gp_Pnt, gp_Trsf +from OCC.TopoDS import TopoDS_Vertex from base import KbeObject +from OCC.BRepTools import BRepTools_TrsfModification + -class Vertex(KbeObject, gp_Pnt): +def make_vertex(*args): + return BRepBuilderAPI_MakeVertex(*args) + +class Vertex(KbeObject, TopoDS_Vertex): """ wraps gp_Pnt """ _n = 0 def __init__(self, x,y,z): """Constructor for KbeVertex""" - gp_Pnt.__init__(self, x,y,z) - KbeObject.__init__(self, - #name='Vertex #{0} {1},{2},{3}'.format(self._n, self.x, self.y, self.z) - name='Vertex #{0}'.format(self._n) - ) - self._n += 1 # should be a property of KbeObject + KbeObject.__init__(self, name='Vertex #{0}'.format(self._n)) + self._n += 1 # should be a property of KbeObject + self._pnt = gp_Pnt(x,y,z) + self._vertex = make_vertex(self._pnt) + TopoDS_Vertex.__init__(self,self._vertex) + + def _update(self): + """ + + """ + # TODO: perhaps should take an argument until which topological level + # topological entities bound to the vertex should be updated too... + from OCC.ShapeBuild import ShapeBuild_ReShape + reshape = ShapeBuild_ReShape() + reshape.Replace(self._vertex, make_vertex(self._pnt)) + #self = Vertex(*self._pnt.Coord()) + @staticmethod def from_vertex(cls, pnt): Vertex.from_pnt(vertex2pnt(pnt)) @@ -32,61 +54,71 @@ def from_vec(cls): @property def x(self): - return self.X() + return self._pnt.X() @x.setter def x(self, val): - self.SetX(val) - self.is_dirty = 1 + self._pnt.SetX(val) + self._update() + #self.is_dirty = 1 @property def y(self): - return self.Y() + return self._pnt.Y() @y.setter def y(self, val): - self.SetY(val) - self.is_dirty = 1 + self._pnt.SetY(val) + self._update() + #self.is_dirty = 1 @property def z(self): - return self.Z() + return self._pnt.Z() @z.setter def z(self, val): - self.SetZ(val) - self.is_dirty = 1 + self._pnt.SetZ(val) + self._update() + #self.is_dirty = 1 + + @property + def xyz(self): + return self._pnt.Coord() + + @xyz.setter + def xyz(self, *val): + self._pnt.SetXYZ(*val) + self._update() + #self.is_dirty = 1 - def __eq__(self, other): - return self.IsEqual(other, TOLERANCE) def __repr__(self): return self.name - @property - def as_topods(self): - '''returns a gp_Vec version of self''' - return make_vertex(self) - @property def as_vec(self): '''returns a gp_Vec version of self''' - pass + return gp_Vec(*self._pnt.Coord()) @property def as_dir(self): '''returns a gp_Vec version of self''' - pass + return gp_Dir(*self._pnt.Coord()) @property def as_xyz(self): '''returns a gp_XYZ version of self''' - pass + return gp_XYZ(*self._pnt.Coord()) + + @property + def as_pnt(self): + return self._pnt @property def as_2d(self): '''returns a gp_Pnt2d version of self''' - pass + return gp_Pnt2d(*self._pnt.Coord()[:2]) diff --git a/src/addons/KBE/wire.py b/src/addons/KBE/wire.py new file mode 100644 index 000000000..3f2a65fdb --- /dev/null +++ b/src/addons/KBE/wire.py @@ -0,0 +1,16 @@ +from OCC.KBE.base import KbeObject +from OCC.TopoDS import TopoDS_Wire, TopoDS_wire + + +class Wire(KbeObject, TopoDS_Wire): + ''' + ''' + + def __init__(self, wire): + ''' + ''' + assert isinstance(wire, TopoDS_wire), 'need a TopoDS_Wire, got a %s'% wire.__class__ + KbeObject.__init__(self, 'wire') + TopoDS_Wire.__init__(self, wire) + + # BRepAdaptor_CompCurve \ No newline at end of file From 845e724299f8a66a2159292360e7d1c0effd297b Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 14:11:49 +0200 Subject: [PATCH 04/29] updated Utils... need that for some cool changes to the OCCViewer... --- src/addons/Utils/Common.py | 31 +++++++++++++++---------------- src/addons/Utils/Construct.py | 9 +++++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/addons/Utils/Common.py b/src/addons/Utils/Common.py index 3c20db136..507f3c582 100644 --- a/src/addons/Utils/Common.py +++ b/src/addons/Utils/Common.py @@ -39,20 +39,21 @@ from OCC.Bnd import * from OCC.BRepBndLib import * +from OCC.GCPnts import GCPnts_UniformDeflection +from OCC.Geom import Handle_Geom_Curve +from OCC.IntAna import IntAna_Int3Pln +from OCC.ShapeFix import ShapeFix_ShapeTolerance from OCC.TColgp import * -from OCC.TColGeom import * from OCC.TColStd import * -from OCC.TCollection import * from OCC.BRepAdaptor import * from OCC.BRepAlgoAPI import * from OCC.GeomAPI import * +from OCC.TopExp import TopExp from OCC.gp import * from OCC.BRepBuilderAPI import * -from OCC.BRepOffsetAPI import * from OCC.TopoDS import * from OCC.Utils.Context import assert_isdone from OCC.KBE.types_lut import ShapeToTopology -from OCC.Quantity import * from OCC.GProp import GProp_GProps from OCC.GeomAbs import * @@ -86,16 +87,16 @@ def _Tcol_dim_1(li, _type): pts.thisown = False return pts -def _Tcol_dim_2(li, _type): - '''function factory for 2-dimensional TCol* types''' - length_nested = len(li[0])-1 - pts = _type(0, len(li)-1, 0, length_nested) - pts.thisown = False - return pts - for n1,i in enumerate(li): - for n2,j in enumerate(i): - pts.SetValue(n1,n2,j) - return pts +# def _Tcol_dim_2(li, _type): +# '''function factory for 2-dimensional TCol* types''' +# length_nested = len(li[0])-1 +# pts = _type(0, len(li)-1, 0, length_nested) +# pts.thisown = False +# return pts +# for n1,i in enumerate(li): +# for n2,j in enumerate(i): +# pts.SetValue(n1,n2,j) +# return pts def point_list_to_TColgp_Array1OfPnt(li): pts = TColgp_Array1OfPnt(0, len(li)-1) @@ -363,8 +364,6 @@ def intersection_from_three_planes( planeA, planeB, planeC, show=False): planeC ) pnt = intersection_planes.Value() - if show: - display.DisplayShape(make_vertex(pnt)) return pnt #def split_edge(edge, pnt): diff --git a/src/addons/Utils/Construct.py b/src/addons/Utils/Construct.py index cf60f6a79..fbcb86d23 100644 --- a/src/addons/Utils/Construct.py +++ b/src/addons/Utils/Construct.py @@ -26,8 +26,11 @@ from __future__ import with_statement # wrapped modules +import warnings from OCC.BRep import BRep_Tool +from OCC.BRepAlgo import BRepAlgo_Cut, BRepAlgo_Fuse from OCC.BRepOffset import BRepOffset_Skin +from OCC.GeomConvert import GeomConvert_ApproxCurve from OCC.GeomLProp import * from OCC.ShapeFix import * from OCC.BRepOffsetAPI import * @@ -49,7 +52,7 @@ # high level from OCC.Utils.Common import * from OCC.Utils.Context import assert_isdone -from OCC.KBE.types_lut import GeometryLookup, ShapeToTopology +from OCC.KBE.types_lut import ShapeToTopology from functools import wraps @@ -687,10 +690,8 @@ def face_normal(face): norm.Reverse() return norm -def face_from_plane(_geom_plane, lowerLimit=-1000, upperLimit=1000, show=False): +def face_from_plane(_geom_plane, lowerLimit=-1000, upperLimit=1000): _trim_plane = make_face( Geom_RectangularTrimmedSurface(_geom_plane.GetHandle(), lowerLimit, upperLimit, lowerLimit, upperLimit).GetHandle() ) - if show: - display.DisplayShape(_trim_plane) return _trim_plane def find_plane_from_shape(shape, tolerance=TOLERANCE): From da7eb91ac44d80bd4759c08cb55635fbb549f555 Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 14:26:27 +0200 Subject: [PATCH 05/29] pretty cool changes to the viewer 1) support for displaying vector 2) heavily optimized DisplayShape version when multiple TopoDS_Shapes instances are given for display. Using the power of the AIS_MultipleConnectedInteractive class, a 10 fold speed increase can be achieved, since the visualization attributes than become shared. think of it as a vectorized version of DisplayShape... 3) ShiftSelect was implemented, such that multiple entities can be selected 4) finally _very_ important is that DisplayShape uses the update=False attr as standard. I probably need to fix this in the examples, but it is _super_ irritating if update=True is the default, since your code will be laudered with update=False statements... it gets _really_ ugly that way... so this is the sane default.... --- src/addons/Display/OCCViewer.py | 257 +++++++++++++++++++++----------- 1 file changed, 169 insertions(+), 88 deletions(-) diff --git a/src/addons/Display/OCCViewer.py b/src/addons/Display/OCCViewer.py index 88de45183..5bc612f74 100644 --- a/src/addons/Display/OCCViewer.py +++ b/src/addons/Display/OCCViewer.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -##Copyright 2008-2011 Thomas Paviot (tpaviot@gmail.com) +##Copyright 2008-2013 Thomas Paviot (tpaviot@gmail.com) ## ##This file is part of pythonOCC. ## @@ -17,11 +17,16 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -import os, os.path, types +import os import sys -import subprocess -from ctypes import util +import math +import itertools +from OCC.AIS import AIS_MultipleConnectedInteractive +from OCC.TopoDS import * +from OCC.Utils.Common import to_string, color +from OCC.Utils.Construct import gp_Dir +from OCC.KBE.types_lut import topo_lut import OCC.Visualization import OCC.V3d import OCC.V2d @@ -30,20 +35,31 @@ import OCC.Quantity import OCC.TopoDS import OCC.Visual3d -import OCC.NIS -import OCC.Prs3d +from OCC import Prs3d +from OCC.Prs3d import Prs3d_Arrow +from OCC.Quantity import Quantity_Color, Quantity_NOC_ORANGE +from OCC.Graphic3d import Graphic3d_NOM_SATIN -from OCC.TopoDS import * +try: + import OCC.NIS + HAVE_NIS = False +except ImportError: + HAVE_NIS = False def set_CSF_GraphicShr(): - # Sets the CSF_GraphicShr env var if not already set up - if not os.environ.has_key('CSF_GraphicShr'): - os.environ['CSF_GraphicShr'] = util.find_library('TKOpenGl') + "Sets the CSF_GraphicShr env var" + from ctypes import util + os.environ['CSF_GraphicShr'] = util.find_library('TKOpenGl') if not (sys.platform == 'win32'): set_CSF_GraphicShr() + +modes = itertools.cycle([TopAbs.TopAbs_FACE, TopAbs.TopAbs_EDGE, TopAbs.TopAbs_VERTEX, + TopAbs.TopAbs_SHELL, TopAbs.TopAbs_SOLID, ]) + + class BaseDriver(object): """ The base driver class for both Driver2d and Driver3d classes @@ -65,8 +81,12 @@ def MoveTo(self,X,Y): self.Context.MoveTo(X,Y,self.View_handle) def FitAll(self): - self.View.ZFitAll() - self.View.FitAll() + if hasattr(self.View, 'Fitall'): + # Viewer2d + self.View.Fitall() + else: + self.View.ZFitAll() + self.View.FitAll() def SetWindow(self,window_handle): self._window_handle = window_handle @@ -84,23 +104,40 @@ def Create(self, create_default_lights = True): self.Context = self.Context_handle.GetObject() self.Viewer = self.Viewer_handle.GetObject() if create_default_lights: - self.Viewer.SetDefaultLights() - self.Viewer.SetLightOn() + try: + self.Viewer.SetDefaultLights() + self.Viewer.SetLightOn() + except AttributeError: + # Viewer2d doesnt have SetDefaultLights attr + pass self.View = self.View_handle.GetObject() self._inited = True + # some preferences; + # the selected elements gray by default... a pretty poor choice I think... + self.Context.SelectionColor(Quantity_NOC_ORANGE) # nessecary for text rendering try: self._struc_mgr = self.Context.MainPrsMgr().GetObject().StructureManager() - except: + except AttributeError: + # Viewer2d doesnt have MainPrsMgr attr pass + + class Viewer3d(BaseDriver, OCC.Visualization.Display3d): def __init__(self, window_handle ): BaseDriver.__init__(self,window_handle) OCC.Visualization.Display3d.__init__(self) self.selected_shape = None - + + def SetDoubleBuffer(self, onoroff): + """enables double buffering + when shapes are moved in the viewer + a very shaky picture is drawn, since double buffering [ a rudimentary OGL capability ] + is disabled by default. Which is a bad default choice, fixed here...""" + self.View.Window().GetObject().SetDoubleBuffer(bool(onoroff)) + def OnResize(self): self.View.MustBeResized() @@ -166,114 +203,144 @@ def SetBackgroundImage(self, filename, Stretch = True): self.View.SetBackgroundImage(filename, OCC.Aspect.Aspect_FM_STRETCH, True) else: self.View.SetBackgroundImage(filename, OCC.Aspect.Aspect_FM_NONE, True ) - - def DisplayMessage(self,point,text_to_write, update=True): + + def DisplayVector(self, vec, pnt, update=False): + if self._inited: + aPresentation = Prs3d.Prs3d_Presentation(self._struc_mgr) + arrow = Prs3d_Arrow() + arrow.Draw( + aPresentation.GetHandle(), + (pnt.as_vec() + vec).as_pnt(), + gp_Dir(vec), + math.radians(20), + vec.Magnitude() + ) + aPresentation.Display() + # it would be more coherent if a AIS_InteractiveObject would be returned + if update: + self.Repaint() + return aPresentation + + def DisplayMessage(self,point,text_to_write, message_color=None, update=False): """ - point: a gp_Pnt instance - text_to_write: a string + :point: a gp_Pnt instance + :text_to_write: a string + :message_color: triple with the range 0-1 """ - # TODO - should be imported! - def to_string_extended(_str): - from OCC.TCollection import TCollection_ExtendedString as String - return String(_str) - - aPresentation = OCC.Prs3d.Prs3d_Presentation(self._struc_mgr) - text_aspect = OCC.Prs3d.Prs3d_TextAspect() - OCC.Prs3d.Prs3d_Text().Draw(aPresentation.GetHandle(), - text_aspect.GetHandle(), - to_string_extended(text_to_write), - point) + aPresentation = Prs3d.Prs3d_Presentation(self._struc_mgr) + text_aspect = Prs3d.Prs3d_TextAspect() + + if message_color is not None: + text_aspect.SetColor(color(*message_color)) + + text = Prs3d.Prs3d_Text() + text.Draw(aPresentation.GetHandle(), + text_aspect.GetHandle(), + to_string(text_to_write), + point) aPresentation.Display() - # it would be more coherent if a AIS_InteractiveObject would be returned + # TODO: it would be more coherent if a AIS_InteractiveObject would be returned if update: self.Repaint() return aPresentation - def DisplayShape(self, shapes, material=None, texture=None, update=False): + + def DisplayShape(self, shapes, material=None, texture=None, color=None, transparency=None, update=False): ''' ''' - + if issubclass(shapes.__class__, TopoDS_Shape): shapes = [shapes] SOLO = True else: SOLO = False - + ais_shapes = [] for shape in shapes: - if material or texture:#careful: != operator segfaults - self.View.SetSurfaceDetail(OCC.V3d.V3d_TEX_ALL) - shape_to_display = OCC.AIS.AIS_TexturedShape(shape) - if material: - shape_to_display.SetMaterial(material) + if material or texture: if texture: + self.View.SetSurfaceDetail(OCC.V3d.V3d_TEX_ALL) + shape_to_display = OCC.AIS.AIS_TexturedShape(shape) filename, toScaleU, toScaleV, toRepeatU, toRepeatV, originU, originV = texture.GetProperties() shape_to_display.SetTextureFileName(OCC.TCollection.TCollection_AsciiString(filename)) shape_to_display.SetTextureMapOn() shape_to_display.SetTextureScale(True, toScaleU, toScaleV) shape_to_display.SetTextureRepeat(True, toRepeatU, toRepeatV) shape_to_display.SetTextureOrigin(True, originU, originV) - shape_to_display.SetDisplayMode(3); - ais_shapes.append(shape_to_display.GetHandle()) + shape_to_display.SetDisplayMode(3) + elif material: + shape_to_display = OCC.AIS.AIS_Shape(shape) + shape_to_display.SetMaterial(material) else: + # TODO: can we use .Set to attach all TopoDS_Shapes to this AIS_Shape instance? shape_to_display = OCC.AIS.AIS_Shape(shape) - ais_shapes.append(shape_to_display.GetHandle()) - if update: - # only update when explicitely told to do so - self.Context.Display(shape_to_display.GetHandle(), True) - # especially this call takes up a lot of time... - self.FitAll() - else: - self.Context.Display(shape_to_display.GetHandle(), False) - + + ais_shapes.append(shape_to_display.GetHandle()) + + if not SOLO: + #=============================================================================== + # computing graphic properties is expensive + # if an iterable is found, so cluster all TopoDS_Shape under a AIS_MultipleConnectedInteractive + #=============================================================================== + shape_to_display = AIS_MultipleConnectedInteractive() + for i in ais_shapes: + shape_to_display.Connect(i) + + #=============================================================================== + # set the graphic properties + #=============================================================================== + + if material is None: + #The default material is too shiny to show the object + #color well, so I set it to something less reflective + shape_to_display.SetMaterial(Graphic3d_NOM_SATIN) + + if color: + if isinstance(color, Quantity_Color): + pass + elif isinstance(color, (tuple, list)): + from OCC.Utils.Common import color as quantity_color + color = quantity_color(*color) + + for shp in ais_shapes: + self.Context.SetColor(shp, color, 0) + + if transparency: + shape_to_display.SetTransparency(transparency) + if update: + # only update when explicitely told to do so + self.Context.Display(shape_to_display.GetHandle(), True) + # especially this call takes up a lot of time... + self.FitAll() + else: + self.Context.Display(shape_to_display.GetHandle(), False) + if SOLO: - return ais_shapes[0] + return ais_shapes[0] else: - return ais_shapes + return shape_to_display - def DisplayColoredShape(self, shapes, color='YELLOW', update=True, ): - ais_shapes = [] + def DisplayColoredShape(self, shapes, color='YELLOW', update=False, ): if isinstance(color, str): dict_color = {'WHITE':OCC.Quantity.Quantity_NOC_WHITE, 'BLUE':OCC.Quantity.Quantity_NOC_BLUE1, 'RED':OCC.Quantity.Quantity_NOC_RED, 'GREEN':OCC.Quantity.Quantity_NOC_GREEN, 'YELLOW':OCC.Quantity.Quantity_NOC_YELLOW, - # new 'CYAN':OCC.Quantity.Quantity_NOC_CYAN1, 'WHITE':OCC.Quantity.Quantity_NOC_WHITE, 'BLACK':OCC.Quantity.Quantity_NOC_BLACK, 'ORANGE':OCC.Quantity.Quantity_NOC_ORANGE, } - color = dict_color[color] - elif isinstance(color, OCC.Quantity.Quantity_Color): - pass + clr = Quantity_Color( dict_color[color] ) + elif isinstance(color, Quantity_Color): + clr = color else: raise ValueError('color should either be a string ( "BLUE" ) or a Quantity_Color(0.1, 0.8, 0.1) got %s' % color) - if issubclass(shapes.__class__, TopoDS_Shape): - shapes = [shapes] - SOLO = True - else: - SOLO = False - - for shape in shapes: - shape_to_display = OCC.AIS.AIS_Shape(shape).GetHandle() - self.Context.SetColor(shape_to_display,color,0) - ais_shapes.append(shape_to_display) - if update: - self.Context.Display(shape_to_display, True) - self.FitAll() - else: - # don't update the view when shape_to_display is added - # comes in handy when adding lots and lots of objects - self.Context.Display(shape_to_display, False) - - if SOLO: - return ais_shapes[0] - else: - return ais_shapes + return self.DisplayShape(shapes, color=clr) + def DisplayTriedron(self): self.View.TriedronDisplay(OCC.Aspect.Aspect_TOTP_RIGHT_LOWER, OCC.Quantity.Quantity_NOC_BLACK, 0.08, OCC.V3d.V3d_WIREFRAME) @@ -303,25 +370,26 @@ def SetSelectionMode(self,mode = OCC.TopAbs.TopAbs_FACE): self.Context.CloseAllContexts() self.Context.OpenLocalContext() self.Context.ActivateStandardMode(mode) - + + def SetSelectionModeVertex(self): self.Context.CloseAllContexts() self.Context.OpenLocalContext() self.Context.ActivateStandardMode(OCC.TopAbs.TopAbs_VERTEX) - + def SetSelectionModeEdge(self): self.Context.CloseAllContexts() self.Context.OpenLocalContext() self.Context.ActivateStandardMode(OCC.TopAbs.TopAbs_EDGE) - + def SetSelectionModeFace(self): self.Context.CloseAllContexts() self.Context.OpenLocalContext() - self.Context.ActivateStandardMode(OCC.TopAbs.TopAbs_FACE) - + self.Context.ActivateStandardMode(OCC.TopAbs.TopAbs_FACE) + def SetSelectionModeShape(self): self.Context.CloseAllContexts() - + def SetSelectionModeNeutral(self): self.Context.CloseAllContexts() @@ -354,7 +422,20 @@ def Select(self,X,Y): print "Current selection (single):",self.selected_shape else: self.selected_shape = None - + + def ShiftSelect(self,X,Y): + self.Context.ShiftSelect() + self.Context.InitSelected() + + self.selected_shapes = [] + while self.Context.MoreSelected(): + if self.Context.HasSelectedShape(): + self.selected_shapes.append(self.Context.SelectedShape()) + self.Context.NextSelected() + # hilight newly selected unhighlight those no longer selected + self.Context.UpdateSelected() + print "Current selection (%i instances):"%len(self.selected_shapes),self.selected_shapes + def Rotation(self,X,Y): self.View.Rotation(X,Y) From 0f5a5918a0fd132651f72c9ea8c3c4f541102a5e Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 14:39:23 +0200 Subject: [PATCH 06/29] mehhh small merging issue ;( --- src/addons/Display/OCCViewer.py | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/src/addons/Display/OCCViewer.py b/src/addons/Display/OCCViewer.py index 5bc612f74..06dfc08fb 100644 --- a/src/addons/Display/OCCViewer.py +++ b/src/addons/Display/OCCViewer.py @@ -41,11 +41,6 @@ from OCC.Graphic3d import Graphic3d_NOM_SATIN -try: - import OCC.NIS - HAVE_NIS = False -except ImportError: - HAVE_NIS = False def set_CSF_GraphicShr(): "Sets the CSF_GraphicShr env var" @@ -124,7 +119,7 @@ def Create(self, create_default_lights = True): pass - + class Viewer3d(BaseDriver, OCC.Visualization.Display3d): def __init__(self, window_handle ): BaseDriver.__init__(self,window_handle) @@ -339,9 +334,9 @@ def DisplayColoredShape(self, shapes, color='YELLOW', update=False, ): else: raise ValueError('color should either be a string ( "BLUE" ) or a Quantity_Color(0.1, 0.8, 0.1) got %s' % color) - return self.DisplayShape(shapes, color=clr) + return self.DisplayShape(shapes, color=clr) + - def DisplayTriedron(self): self.View.TriedronDisplay(OCC.Aspect.Aspect_TOTP_RIGHT_LOWER, OCC.Quantity.Quantity_NOC_BLACK, 0.08, OCC.V3d.V3d_WIREFRAME) self.Repaint() @@ -366,27 +361,11 @@ def Tumble(self,NumImages,Animation = True): def Pan(self,Dx,Dy): self.View.Pan(Dx,Dy) - def SetSelectionMode(self,mode = OCC.TopAbs.TopAbs_FACE): + def SetSelectionMode(self, mode=None): self.Context.CloseAllContexts() self.Context.OpenLocalContext() self.Context.ActivateStandardMode(mode) - - def SetSelectionModeVertex(self): - self.Context.CloseAllContexts() - self.Context.OpenLocalContext() - self.Context.ActivateStandardMode(OCC.TopAbs.TopAbs_VERTEX) - - def SetSelectionModeEdge(self): - self.Context.CloseAllContexts() - self.Context.OpenLocalContext() - self.Context.ActivateStandardMode(OCC.TopAbs.TopAbs_EDGE) - - def SetSelectionModeFace(self): - self.Context.CloseAllContexts() - self.Context.OpenLocalContext() - self.Context.ActivateStandardMode(OCC.TopAbs.TopAbs_FACE) - def SetSelectionModeShape(self): self.Context.CloseAllContexts() From 0b5093d24ec0f448119fdeb81b23091a06e3b6e1 Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 15:11:50 +0200 Subject: [PATCH 07/29] something very creepy and Heisenbergian is going on... looks like the IDE is reverting changes I just made... really scary... --- src/addons/Utils/Common.py | 1171 ++++++++++++++++++--------------- src/addons/Utils/Construct.py | 280 +++++++- 2 files changed, 877 insertions(+), 574 deletions(-) diff --git a/src/addons/Utils/Common.py b/src/addons/Utils/Common.py index 507f3c582..712bcbd33 100644 --- a/src/addons/Utils/Common.py +++ b/src/addons/Utils/Common.py @@ -1,539 +1,632 @@ -from __future__ import with_statement - - -# -*- coding: iso-8859-1 -*- -#! /usr/bin/python - -##Copyright 2009-2011 Jelle Feringa -## -##jelle.feringa@gmail.com -## -##pythonOCC is a computer program whose purpose is to provide a complete set -##of python bindings for OpenCasacde library. -## -##This software is governed by the CeCILL license under French law and -##abiding by the rules of distribution of free software. You can use, -##modify and/ or redistribute the software under the terms of the CeCILL -##license as circulated by CEA, CNRS and INRIA at the following URL -##"http://www.cecill.info". -## -##As a counterpart to the access to the source code and rights to copy, -##modify and redistribute granted by the license, users are provided only -##with a limited warranty and the software's author, the holder of the -##economic rights, and the successive licensors have only limited -##liability. -## -##In this respect, the user's attention is drawn to the risks associated -##with loading, using, modifying and/or developing or reproducing the -##software by the user in light of its specific status of free software, -##that may mean that it is complicated to manipulate, and that also -##therefore means that it is reserved for developers and experienced -##professionals having in-depth computer knowledge. Users are therefore -##encouraged to load and test the software's suitability as regards their -##requirements in conditions enabling the security of their systems and/or -##data to be ensured and, more generally, to use and operate it in the -##same conditions as regards security. -## -##The fact that you are presently reading this means that you have had -##knowledge of the CeCILL license and that you accept its terms. - -from OCC.Bnd import * -from OCC.BRepBndLib import * -from OCC.GCPnts import GCPnts_UniformDeflection -from OCC.Geom import Handle_Geom_Curve -from OCC.IntAna import IntAna_Int3Pln -from OCC.ShapeFix import ShapeFix_ShapeTolerance -from OCC.TColgp import * -from OCC.TColStd import * -from OCC.BRepAdaptor import * -from OCC.BRepAlgoAPI import * -from OCC.GeomAPI import * -from OCC.TopExp import TopExp -from OCC.gp import * -from OCC.BRepBuilderAPI import * -from OCC.TopoDS import * -from OCC.Utils.Context import assert_isdone -from OCC.KBE.types_lut import ShapeToTopology -from OCC.GProp import GProp_GProps -from OCC.GeomAbs import * - -TOLERANCE = 1e-6 - -def get_boundingbox(shape, tol=1e-12): - ''' - :param shape: TopoDS_Shape such as TopoDS_Face - :param tol: tolerance - :return: xmin, ymin, zmin, xmax, ymax, zmax - ''' - bbox = Bnd_Box() - bbox.SetGap(tol) - #BRepBndLib_AddClose(shape, bbox) - BRepBndLib_Add(shape, bbox) - return bbox - -#=============================================================================== -# Data type utilities -#=============================================================================== - -def to_string(_string): - from OCC.TCollection import TCollection_ExtendedString - return TCollection_ExtendedString(_string) - -def _Tcol_dim_1(li, _type): - '''function factory for 1-dimensional TCol* types''' - pts = _type(0, len(li)-1) - for n,i in enumerate(li): - pts.SetValue(n,i) - pts.thisown = False - return pts - -# def _Tcol_dim_2(li, _type): -# '''function factory for 2-dimensional TCol* types''' -# length_nested = len(li[0])-1 -# pts = _type(0, len(li)-1, 0, length_nested) -# pts.thisown = False -# return pts -# for n1,i in enumerate(li): -# for n2,j in enumerate(i): -# pts.SetValue(n1,n2,j) -# return pts - -def point_list_to_TColgp_Array1OfPnt(li): - pts = TColgp_Array1OfPnt(0, len(li)-1) - for n,i in enumerate(li): - pts.SetValue(n,i) - return pts - -def point2d_list_to_TColgp_Array1OfPnt2d(li): - return _Tcol_dim_1(li, TColgp_Array1OfPnt2d) - -#=============================================================================== -# --- BOOLEAN OPERATIONS AS FUNCTIONS --- -#=============================================================================== -def boolean_cut(shapeToCutFrom, cuttingShape): - try: - cut = BRepAlgoAPI_Cut(shapeToCutFrom, cuttingShape) - print 'can work?', cut.BuilderCanWork() - _error = { - 0: '- Ok', - 1: '- The Object is created but Nothing is Done', - 2: '- Null source shapes is not allowed', - 3: '- Check types of the arguments', - 4: '- Can not allocate memory for the DSFiller', - 5: '- The Builder can not work with such types of arguments', - 6: '- Unknown operation is not allowed', - 7: '- Can not allocate memory for the Builder', - } - print 'error status:', _error[cut.ErrorStatus()] - cut.RefineEdges() - cut.FuseEdges() - shp = cut.Shape() - cut.Destroy() - return shp - except: - print 'FAILED TO BOOLEAN CUT' - return shapeToCutFrom - -def boolean_cut_old(shapeToCutFrom, cuttingShape): - from OCC.BRepAlgo import BRepAlgo_Cut - cut = BRepAlgo_Cut(shapeToCutFrom, cuttingShape) - #cut.RefineEdges() - #cut.FuseEdges() - shp = cut.Shape() - return shp - -def boolean_fuse(shapeToCutFrom, joiningShape): - join = BRepAlgoAPI_Fuse(shapeToCutFrom, joiningShape) - join.RefineEdges() - join.FuseEdges() - shape = join.Shape() - join.Destroy() - return shape - -#=============================================================================== -# --- INTERPOLATION --- -#=============================================================================== - -def filter_points_by_distance( list_of_point, distance=0.1): - ''' - get rid of those point that lie within tolerance of a consequtive series of points - ''' - tmp = [list_of_point[0]] - for a in list_of_point[1:]: - if any([a.IsEqual(i, distance) for i in tmp]): - continue - else: - tmp.append(a) - return tmp - -def points_to_bspline(pnts): - ''' - - ''' - pnts = point_list_to_TColgp_Array1OfPnt(pnts) - crv = GeomAPI_PointsToBSpline(pnts) - return crv.Curve() - -def interpolate_points_to_spline(list_of_points, start_tangent, end_tangent, filter_pts=True, tolerance=TOLERANCE): - ''' - GeomAPI_Interpolate is buggy: need to use `fix` in order to get the right points in... - - ''' - def fix(li, _type): - '''function factory for 1-dimensional TCol* types''' - pts = _type(1, len(li)) - for n,i in enumerate(li): - pts.SetValue(n+1,i) - pts.thisown = False - return pts - - if filter_pts: - list_of_points = filter_points_by_distance(list_of_points, 0.1) - - yyy = fix(list_of_points, TColgp_HArray1OfPnt) - try: - rrr = GeomAPI_Interpolate(yyy.GetHandle(), False, tolerance ) - rrr.Load(start_tangent, end_tangent, False) - rrr.Perform() - if rrr.IsDone(): - return rrr.Curve() - except RuntimeError: - print 'FAILED TO INTERPOLATE THE SHOWN POINTS' - -def interpolate_points_vectors_to_spline(list_of_points, list_of_vectors, vector_mask=[], tolerance=TOLERANCE): - ''' - build a curve from a set of points and vectors - the vectors describe the tangent vector at the corresponding point - ''' - # GeomAPI_Interpolate is buggy: need to use `fix` in order to get the right points in... - assert len(list_of_points) == len(list_of_vectors), 'vector and point list not of same length' - def fix(li, _type): - '''function factory for 1-dimensional TCol* types''' - pts = _type(1, len(li)) - for n,i in enumerate(li): - pts.SetValue(n+1,i) - pts.thisown = False - return pts - - if not vector_mask == []: - assert len(vector_mask)==len(list_of_points), 'length vector mask is not of length points list nor []' - else: - vector_mask = [True for i in range(len(list_of_points))] - - xxx = fix(vector_mask, TColStd_HArray1OfBoolean) - yyy = fix(list_of_points, TColgp_HArray1OfPnt) - zzz = fix(list_of_vectors, TColgp_Array1OfVec) - - try: - rrr = GeomAPI_Interpolate(yyy.GetHandle(), False, tolerance ) - rrr.Load(zzz, xxx.GetHandle(), False) - rrr.Perform() - if rrr.IsDone(): - return rrr.Curve() - except RuntimeError: - # the exception was unclear - raise RuntimeError('FAILED TO INTERPOLATE THE POINTS') - -def interpolate_points_to_spline_no_tangency(list_of_points, filter=True, closed=False, tolerance=TOLERANCE): - ''' - GeomAPI_Interpolate is buggy: need to use `fix` in order to get the right points in... - - ''' - def fix(li, _type): - '''function factory for 1-dimensional TCol* types''' - pts = _type(1, len(li)) - for n,i in enumerate(li): - pts.SetValue(n+1,i) - pts.thisown = False - return pts - - list_of_points = filter_points_by_distance(list_of_points, 0.1) - yyy = fix(list_of_points, TColgp_HArray1OfPnt) - try: - rrr = GeomAPI_Interpolate(yyy.GetHandle(), closed, tolerance ) - rrr.Perform() - if rrr.IsDone(): - return rrr.Curve() - except RuntimeError: - # the exception was unclear - raise RuntimeError('FAILED TO INTERPOLATE THE POINTS') - -#=============================================================================== -# --- RANDOMNESS --- -#=============================================================================== - -def random_vec(): - import random - x,y,z = [random.uniform(-1,1) for i in range(3)] - return gp_Vec(x,y,z) - -def random_colored_material_aspect(): - from OCC import Graphic3d - import random - #asp = Graphic3d.Graphic3d_MaterialAspect() - #cc = asp.Color() - - clrs = [ i for i in dir(Graphic3d) if i.startswith('Graphic3d_NOM_') ] - #red, green, blue, opacity = random.uniform(0,1),random.uniform(0,1),random.uniform(0,1), random.uniform(0,1) - #cc.SetValues(red,green,blue, Quantity_TOC_RGB) - color = random.sample(clrs, 1)[0] - print 'color', color - return Graphic3d.Graphic3d_MaterialAspect(getattr(Graphic3d, color)) - #return asp - - -#=============================================================================== -# --- BUILD PATCHES --- -#=============================================================================== - -def common_vertex(edg1, edg2): - te = TopExp() - vert = TopoDS_Vertex() - if te.CommonVertex(edg1, edg2, vert): - return vert - else: - raise ValueError('no common vertex found') - -def midpoint(pntA, pntB): - ''' - computes the point that lies in the middle between pntA and pntB - @param pntA: gp_Pnt - @param pntB: gp_Pnt - ''' - vec1 = gp_Vec(pntA.XYZ()) - vec2 = gp_Vec(pntB.XYZ()) - veccie = (vec1+vec2)/2. - return gp_Pnt( veccie.XYZ() ) - -def center_boundingbox(shape): - ''' - compute the center point of a TopoDS_Shape, based on its bounding box - @param shape: TopoDS_* instance - returns a gp_Pnt instance - ''' - bbox = get_boundingbox(shape, 1e-6) - xmin,ymin,zmin, xmax, ymax, zmax = bbox.Get() - return midpoint(gp_Pnt(xmin,ymin,zmin), gp_Pnt(xmax,ymax,zmax)) - -def point_in_boundingbox(solid, pnt, tolerance=1e-5): - """returns True if *pnt* lies in *boundingbox*, False if not - this is a much speedier test than checking the TopoDS_Solid - Args: - solid TopoDS_Solid - pnt: gp_Pnt - - Returns: bool - """ - return not(get_boundingbox(solid).IsOut(pnt)) - -def point_in_solid(solid, pnt, tolerance=1e-5): - """returns True if *pnt* lies in *solid*, False if not - Args: - solid TopoDS_Solid - pnt: gp_Pnt - - Returns: bool - """ - from OCC.BRepClass3d import BRepClass3d_SolidClassifier - from OCC.TopAbs import TopAbs_ON, TopAbs_OUT, TopAbs_IN - _in_solid = BRepClass3d_SolidClassifier(solid, pnt, tolerance) - print 'STATE',_in_solid.State() - if _in_solid.State()==TopAbs_ON: - return None,'on' - if _in_solid.State()==TopAbs_OUT: - return False,'out' - if _in_solid.State()==TopAbs_IN: - return True,'in' - -def intersection_from_three_planes( planeA, planeB, planeC, show=False): - ''' - intersection from 3 planes - accepts both Geom_Plane and gp_Pln - @param planeA: - @param planeB: - @param planeC: - @param show: - ''' - planeA = planeA if not isinstance(planeA, gp_Pln) else planeA.Pln() - planeB = planeB if not isinstance(planeB, gp_Pln) else planeB.Pln() - planeC = planeC if not isinstance(planeC, gp_Pln) else planeC.Pln() - - - intersection_planes = IntAna_Int3Pln( planeA, - planeB, - planeC - ) - pnt = intersection_planes.Value() - return pnt - -#def split_edge(edge, pnt): -# ''' -# -# @param edge: -# @param pnt: -# ''' - -#=============================================================================== -# --- TRANSFORM --- -#=============================================================================== - -def translate_topods_from_vector(brep, vec, copy=False): - ''' - translate a brep over a vector - @param brep: the Topo_DS to translate - @param vec: the vector defining the translation - @param copy: copies to brep if True - ''' - trns = gp_Trsf() - trns.SetTranslation(vec) - brep_trns = BRepBuilderAPI_Transform(brep, trns, copy) - brep_trns.Build() - return brep_trns.Shape() - -def normal_vector_from_plane(plane, vec_length=1): - ''' - returns a vector normal to the plane of length vec_length - @param plane: - ''' - trns = gp_Vec(plane.Axis().Direction()) - trns.Normalized() * vec_length - return trns - -#=============================================================================== -# FIX -#=============================================================================== -def fix_tolerance( shape, tolerance=TOLERANCE): - ShapeFix_ShapeTolerance().SetTolerance(shape, tolerance) - -def fix_continuity(edge, continuity=1): - from OCC.ShapeUpgrade import ShapeUpgrade_ShapeDivideContinuity - su = ShapeUpgrade_ShapeDivideContinuity(edge) - su.SetBoundaryCriterion(eval('GeomAbs_C'+str(continuity))) - su.Perform() - st = ShapeToTopology() - te = st(su.Result()) - return te - -def resample_curve_with_uniform_deflection(curve, deflection=0.5, degreeMin=3, degreeMax=8, continuity=GeomAbs_C2, tolerance=1e-4): - ''' - fits a bspline through the samples on `curve` - @param curve: TopoDS_Wire, TopoDS_Edge, curve - @param n_samples: - ''' - crv = to_adaptor_3d(curve) - defl = GCPnts_UniformDeflection(crv, deflection) - with assert_isdone(defl, 'failed to compute UniformDeflection'): - print 'number of points:', defl.NbPoints() - sampled_pnts = [defl.Value(i) for i in xrange(1, defl.NbPoints())] - resampled_curve = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(sampled_pnts), degreeMin, degreeMax, continuity, tolerance) - return resampled_curve.Curve().GetObject() - -#=============================================================================== -# global properties -#=============================================================================== -class GpropsFromShape(object): - def __init__(self, shape, tolerance=1e-5): - from OCC.BRepGProp import BRepGProp - self.shape = shape - self.bgprop = BRepGProp() - self.tolerance = tolerance - - def volume(self): - '''returns the volume of a solid - ''' - prop = GProp_GProps() - error = self.bgprop.VolumeProperties(self.shape, prop, self.tolerance) - return prop - - def surface(self): - '''returns the area of a surface - ''' - prop = GProp_GProps() - error = self.bgprop.SurfaceProperties(self.shape, prop, self.tolerance) - return prop - - def linear(self): - '''returns the length of a wire or edge - ''' - prop = GProp_GProps() - error = self.bgprop.LinearProperties(self.shape, prop ) - return prop - -def curve_length(crv): - ''' - get the length from a TopoDS_Edge or TopoDS_Wire - ''' - assert isinstance(crv,(TopoDS_Wire, TopoDS_Edge)), 'either a wire or edge...' - gprop = GpropsFromShape(crv) - return gprop.linear().Mass() - - -#======================================================================= -# Distance -#======================================================================= - -def minimum_distance(shp1, shp2): - ''' - compute minimum distance between 2 BREP's - @param shp1: any TopoDS_* - @param shp2: any TopoDS_* - - @return: minimum distance, - minimum distance points on shp1 - minimum distance points on shp2 - ''' - from OCC.BRepExtrema import BRepExtrema_DistShapeShape - bdss = BRepExtrema_DistShapeShape(shp1, shp2) - bdss.Perform() - with assert_isdone(bdss, 'failed computing minimum distances'): - min_dist = bdss.Value() - min_dist_shp1, min_dist_shp2 = [],[] - for i in range(1,bdss.NbSolution()): - min_dist_shp1.append(bdss.PointOnShape1(i)) - min_dist_shp1.append(bdss.PointOnShape2(i)) - return min_dist, min_dist_shp1, min_dist_shp2 - -def vertex2pnt(vertex): - '''returns a gp_Pnt from a TopoDS_Vertex - ''' - from OCC.BRep import BRep_Tool - return BRep_Tool.Pnt(vertex) - -def to_adaptor_3d(curveType): - ''' - abstract curve like type into an adaptor3d - @param curveType: - ''' - from OCC.BRepAdaptor import BRepAdaptor_CompCurve - from OCC.GeomAdaptor import GeomAdaptor_Curve - from OCC.Geom import Geom_Curve - if isinstance(curveType, TopoDS_Wire): - return BRepAdaptor_CompCurve(curveType) - elif isinstance(curveType, TopoDS_Edge): - return BRepAdaptor_Curve(curveType) - elif issubclass(curveType.__class__, Geom_Curve): - return GeomAdaptor_Curve(curveType.GetHandle()) - elif isinstance(curveType, Handle_Geom_Curve): - _crv = curveType.GetObject() - if issubclass(_crv.__class__, Geom_Curve): - return GeomAdaptor_Curve(curveType) - else: - raise TypeError('allowed types are Wire, Edge or a subclass of Geom_Curve\nGot a %s' % (curveType.__class__)) - -def project_point_on_curve(crv, pnt): - from OCC.GeomAPI import GeomAPI_ProjectPointOnCurve - rrr = GeomAPI_ProjectPointOnCurve(pnt, crv) - return rrr.LowerDistanceParameter(), rrr.NearestPoint() - -def wire_to_curve(wire, tolerance=TOLERANCE, order=GeomAbs_C2, max_segment=200, max_order=12): - ''' - a wire can consist of many edges. - these edges are merged given a tolerance and a curve - @param wire: - ''' - adap = BRepAdaptor_CompCurve(wire) - hadap = BRepAdaptor_HCompCurve(adap) - from OCC.Approx import Approx_Curve3d - approx = Approx_Curve3d(hadap.GetHandle(), tolerance, order, max_segment, max_order) - with assert_isdone(approx, 'not able to compute approximation from wire'): - return approx.Curve().GetObject() \ No newline at end of file +# -*- coding: iso-8859-1 -*- +#! /usr/bin/python + +##Copyright 2009-2011 Jelle Feringa +## +##jelle.feringa@gmail.com +## +##pythonOCC is a computer program whose purpose is to provide a complete set +##of python bindings for OpenCasacde library. +## +##This software is governed by the CeCILL license under French law and +##abiding by the rules of distribution of free software. You can use, +##modify and/ or redistribute the software under the terms of the CeCILL +##license as circulated by CEA, CNRS and INRIA at the following URL +##"http://www.cecill.info". +## +##As a counterpart to the access to the source code and rights to copy, +##modify and redistribute granted by the license, users are provided only +##with a limited warranty and the software's author, the holder of the +##economic rights, and the successive licensors have only limited +##liability. +## +##In this respect, the user's attention is drawn to the risks associated +##with loading, using, modifying and/or developing or reproducing the +##software by the user in light of its specific status of free software, +##that may mean that it is complicated to manipulate, and that also +##therefore means that it is reserved for developers and experienced +##professionals having in-depth computer knowledge. Users are therefore +##encouraged to load and test the software's suitability as regards their +##requirements in conditions enabling the security of their systems and/or +##data to be ensured and, more generally, to use and operate it in the +##same conditions as regards security. +## +##The fact that you are presently reading this means that you have had +##knowledge of the CeCILL license and that you accept its terms. + +import random + +from OCC.Bnd import * +from OCC.BRepBndLib import * +from OCC.TColgp import * +from OCC.TColStd import * +from OCC.BRepAdaptor import * +from OCC.GeomAPI import * +from OCC.gp import * +from OCC.BRepBuilderAPI import * +from OCC.TopoDS import * +from OCC.Utils.Context import assert_isdone +from OCC.KBE.types_lut import ShapeToTopology +from OCC.Quantity import * +from OCC.GProp import GProp_GProps +from OCC.GeomAbs import * +from OCC import Graphic3d + + +#=============================================================================== +# No PythonOCC dependencies... +#=============================================================================== + +def roundlist(li, n_decimals=3): + return [round(i,n_decimals) for i in li] + +#=============================================================================== +# CONSTANTS +#=============================================================================== + +TOLERANCE = 1e-6 + +def get_boundingbox(shape, tol=TOLERANCE, vec=False): + ''' + :param shape: TopoDS_Shape such as TopoDS_Face + :param tol: tolerance + :return: xmin, ymin, zmin, xmax, ymax, zmax + ''' + bbox = Bnd_Box() + bbox.SetGap(tol) + #BRepBndLib_AddClose(shape, bbox) + tmp = BRepBndLib_Add(shape, bbox) + xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() + if vec is False: + return xmin, ymin, zmin, xmax, ymax, zmax + else: + return gp_Vec(xmin, ymin, zmin), gp_Vec( xmax, ymax, zmax ) + +def smooth_pnts(pnts): + smooth = [pnts[0]] + for i in range(1, len(pnts)-1): + prev = pnts[i-1] + this = pnts[i] + next = pnts[i+1] + pt = (prev+this+next) / 3.0 + smooth.append(pt) + smooth.append(pnts[-1]) + return smooth + +#=============================================================================== +# Data type utilities +#=============================================================================== + +def color(r,g,b): + return Quantity_Color(r,g,b, Quantity_TOC_RGB) + +def to_string(_string): + from OCC.TCollection import TCollection_ExtendedString + return TCollection_ExtendedString(_string) + +def to_tcol_(_list, type): + array = type(1, len(_list)+1) + for n,i in enumerate(_list): + array.SetValue(n+1,i) + return array.GetHandle() + +def _Tcol_dim_1(li, _type): + '''function factory for 1-dimensional TCol* types''' + pts = _type(0, len(li)-1) + for n,i in enumerate(li): + pts.SetValue(n,i) + pts.thisown = False + return pts + +# def _Tcol_dim_2(li, _type): +# '''function factory for 2-dimensional TCol* types''' +# length_nested = len(li[0])-1 +# pts = _type(0, len(li)-1, 0, length_nested) +# pts.thisown = False +# return pts +# for n1,i in enumerate(li): +# for n2,j in enumerate(i): +# pts.SetValue(n1,n2,j) +# return pts + +def point_list_to_TColgp_Array1OfPnt(li): + pts = TColgp_Array1OfPnt(0, len(li)-1) + for n,i in enumerate(li): + pts.SetValue(n,i) + return pts + +def point2d_list_to_TColgp_Array1OfPnt2d(li): + return _Tcol_dim_1(li, TColgp_Array1OfPnt2d) + +#=============================================================================== +# --- BOOLEAN OPERATIONS AS FUNCTIONS --- +#=============================================================================== +def boolean_cut(shapeToCutFrom, cuttingShape): + from OCC.BRepAlgoAPI import BRepAlgoAPI_Cut + try: + cut = BRepAlgoAPI_Cut(shapeToCutFrom, cuttingShape) + print 'can work?', cut.BuilderCanWork() + _error = { + 0: '- Ok', + 1: '- The Object is created but Nothing is Done', + 2: '- Null source shapes is not allowed', + 3: '- Check types of the arguments', + 4: '- Can not allocate memory for the DSFiller', + 5: '- The Builder can not work with such types of arguments', + 6: '- Unknown operation is not allowed', + 7: '- Can not allocate memory for the Builder', + } + print 'error status:', _error[cut.ErrorStatus()] + cut.RefineEdges() + cut.FuseEdges() + shp = cut.Shape() + cut.Destroy() + return shp + except: + print 'FAILED TO BOOLEAN CUT' + return shapeToCutFrom + +def boolean_cut_old(shapeToCutFrom, cuttingShape): + from OCC.BRepAlgo import BRepAlgo_Cut + cut = BRepAlgo_Cut(shapeToCutFrom, cuttingShape) + #cut.RefineEdges() + #cut.FuseEdges() + shp = cut.Shape() + return shp + +def boolean_fuse(shapeToCutFrom, joiningShape): + from OCC.BRepAlgoAPI import BRepAlgoAPI_Fuse + join = BRepAlgoAPI_Fuse(shapeToCutFrom, joiningShape) + join.RefineEdges() + join.FuseEdges() + shape = join.Shape() + join.Destroy() + return shape + +#=============================================================================== +# --- INTERPOLATION --- +#=============================================================================== + +def filter_points_by_distance( list_of_point, distance=0.1): + ''' + get rid of those point that lie within tolerance of a consequtive series of points + ''' + tmp = [list_of_point[0]] + for a in list_of_point[1:]: + if any([a.IsEqual(i, distance) for i in tmp]): + continue + else: + tmp.append(a) + return tmp + + +def points_to_bspline(pnts): + ''' + + ''' + pnts = point_list_to_TColgp_Array1OfPnt(pnts) + crv = GeomAPI_PointsToBSpline(pnts) + return crv.Curve() + +def interpolate_points_to_spline(list_of_points, start_tangent, end_tangent, filter_pts=True, tolerance=TOLERANCE): + ''' + GeomAPI_Interpolate is buggy: need to use `fix` in order to get the right points in... + + ''' + def fix(li, _type): + '''function factory for 1-dimensional TCol* types''' + pts = _type(1, len(li)) + for n,i in enumerate(li): + pts.SetValue(n+1,i) + pts.thisown = False + return pts + + if filter_pts: + list_of_points = filter_points_by_distance(list_of_points, 0.1) + + yyy = fix(list_of_points, TColgp_HArray1OfPnt) + try: + rrr = GeomAPI_Interpolate(yyy.GetHandle(), False, tolerance ) + rrr.Load(start_tangent, end_tangent, False) + rrr.Perform() + if rrr.IsDone(): + return rrr.Curve() + except RuntimeError: + print 'FAILED TO INTERPOLATE THE SHOWN POINTS' + +def interpolate_points_vectors_to_spline(list_of_points, list_of_vectors, vector_mask=[], tolerance=TOLERANCE): + ''' + build a curve from a set of points and vectors + the vectors describe the tangent vector at the corresponding point + ''' + # GeomAPI_Interpolate is buggy: need to use `fix` in order to get the right points in... + assert len(list_of_points) == len(list_of_vectors), 'vector and point list not of same length' + def fix(li, _type): + '''function factory for 1-dimensional TCol* types''' + pts = _type(1, len(li)) + for n,i in enumerate(li): + pts.SetValue(n+1,i) + pts.thisown = False + return pts + + if not vector_mask == []: + assert len(vector_mask)==len(list_of_points), 'length vector mask is not of length points list nor []' + else: + vector_mask = [True for i in range(len(list_of_points))] + + xxx = fix(vector_mask, TColStd_HArray1OfBoolean) + yyy = fix(list_of_points, TColgp_HArray1OfPnt) + zzz = fix(list_of_vectors, TColgp_Array1OfVec) + + try: + rrr = GeomAPI_Interpolate(yyy.GetHandle(), False, tolerance ) + rrr.Load(zzz, xxx.GetHandle(), False) + rrr.Perform() + if rrr.IsDone(): + return rrr.Curve() + except RuntimeError: + # the exception was unclear + raise RuntimeError('FAILED TO INTERPOLATE THE POINTS') + +def interpolate_points_to_spline_no_tangency(list_of_points, filter=True, closed=False, tolerance=TOLERANCE): + ''' + GeomAPI_Interpolate is buggy: need to use `fix` in order to get the right points in... + + ''' + def fix(li, _type): + '''function factory for 1-dimensional TCol* types''' + pts = _type(1, len(li)) + for n,i in enumerate(li): + pts.SetValue(n+1,i) + pts.thisown = False + return pts + + list_of_points = filter_points_by_distance(list_of_points, 0.1) + yyy = fix(list_of_points, TColgp_HArray1OfPnt) + try: + rrr = GeomAPI_Interpolate(yyy.GetHandle(), closed, tolerance ) + rrr.Perform() + if rrr.IsDone(): + return rrr.Curve() + except RuntimeError: + # the exception was unclear + raise RuntimeError('FAILED TO INTERPOLATE THE POINTS') + +#=============================================================================== +# --- RANDOMNESS --- +#=============================================================================== + +def random_vec(): + import random + x,y,z = [random.uniform(-1,1) for i in range(3)] + return gp_Vec(x,y,z) + +def random_colored_material_aspect(): + import random + #asp = Graphic3d.Graphic3d_MaterialAspect() + #cc = asp.Color() + + clrs = [ i for i in dir(Graphic3d) if i.startswith('Graphic3d_NOM_') ] + #red, green, blue, opacity = random.uniform(0,1),random.uniform(0,1),random.uniform(0,1), random.uniform(0,1) + #cc.SetValues(red,green,blue, Quantity_TOC_RGB) + color = random.sample(clrs, 1)[0] + print 'color', color + return Graphic3d.Graphic3d_MaterialAspect(getattr(Graphic3d, color)) + #return asp + +def random_color(): + return color(random.random(),random.random(),random.random()) + +#=============================================================================== +# --- BUILD PATCHES --- +#=============================================================================== + +def common_vertex(edg1, edg2): + from OCC.TopExp import TopExp + te = TopExp() + vert = TopoDS_Vertex() + if te.CommonVertex(edg1, edg2, vert): + return vert + else: + raise ValueError('no common vertex found') + +def midpoint(pntA, pntB): + ''' + computes the point that lies in the middle between pntA and pntB + @param pntA: gp_Pnt + @param pntB: gp_Pnt + ''' + vec1 = gp_Vec(pntA.XYZ()) + vec2 = gp_Vec(pntB.XYZ()) + veccie = (vec1+vec2)/2. + return gp_Pnt( veccie.XYZ() ) + +def center_boundingbox(shape): + ''' + compute the center point of a TopoDS_Shape, based on its bounding box + @param shape: TopoDS_* instance + returns a gp_Pnt instance + ''' + xmin,ymin,zmin, xmax, ymax, zmax = get_boundingbox(shape, 1e-6) + return midpoint(gp_Pnt(xmin,ymin,zmin), gp_Pnt(xmax,ymax,zmax)) + +def point_in_boundingbox(solid, pnt, tolerance=1e-5): + """returns True if *pnt* lies in *boundingbox*, False if not + this is a much speedier test than checking the TopoDS_Solid + Args: + solid TopoDS_Solid + pnt: gp_Pnt + + Returns: bool + """ + return not(get_boundingbox(solid).IsOut(pnt)) + +def point_in_solid(solid, pnt, tolerance=1e-5): + """returns True if *pnt* lies in *solid*, False if not + Args: + solid TopoDS_Solid + pnt: gp_Pnt + + Returns: bool + """ + from OCC.BRepClass3d import BRepClass3d_SolidClassifier + from OCC.TopAbs import TopAbs_ON, TopAbs_OUT, TopAbs_IN + _in_solid = BRepClass3d_SolidClassifier(solid, pnt, tolerance) + print 'STATE',_in_solid.State() + if _in_solid.State()==TopAbs_ON: + return None,'on' + if _in_solid.State()==TopAbs_OUT: + return False,'out' + if _in_solid.State()==TopAbs_IN: + return True,'in' + +def intersection_from_three_planes( planeA, planeB, planeC): + ''' + intersection from 3 planes + accepts both Geom_Plane and gp_Pln + @param planeA: + @param planeB: + @param planeC: + @param show: + ''' + from OCC.IntAna import IntAna_Int3Pln + + planeA = planeA if not hasattr(planeA, 'Pln') else planeA.Pln() + planeB = planeB if not hasattr(planeB, 'Pln') else planeB.Pln() + planeC = planeC if not hasattr(planeC, 'Pln') else planeC.Pln() + + intersection_planes = IntAna_Int3Pln( planeA, + planeB, + planeC + ) + pnt = intersection_planes.Value() + return pnt + +def intersect_shape_by_line(topods_shape, line, low_parameter=0.0, hi_parameter=float("+inf")): + """ + finds the intersection of a shape and a line + + :param shape: any TopoDS_* + :param line: gp_Lin + :param low_parameter: + :param hi_parameter: + + :return: a list with a number of tuples that corresponds to the number of intersections found + the tuple contains ( gp_Pnt, TopoDS_Face, u,v,w ), respectively the intersection point, the intersecting face + and the u,v,w parameters of the intersection point + :raise: + """ + from OCC.IntCurvesFace import IntCurvesFace_ShapeIntersector + iii = IntCurvesFace_ShapeIntersector() + iii.Load(topods_shape, TOLERANCE) + iii.PerformNearest(line, low_parameter, hi_parameter) + + with assert_isdone(iii, "failed to computer shape / line intersection"): + return (iii.Pnt(1), iii.Face(1), iii.UParameter(1), iii.VParameter(1), iii.WParameter(1)) + # return [(iii.Pnt(i), iii.Face(i), iii.UParameter(i), iii.VParameter(i), iii.WParameter(i)) for i in range(1, iii.NbPnt()+1)] + + +#def split_edge(edge, pnt): +# ''' +# +# @param edge: +# @param pnt: +# ''' + +#=============================================================================== +# --- TRANSFORM --- +#=============================================================================== + +def translate_topods_from_vector(brep, vec, copy=False): + ''' + translate a brep over a vector + @param brep: the Topo_DS to translate + @param vec: the vector defining the translation + @param copy: copies to brep if True + ''' + trns = gp_Trsf() + trns.SetTranslation(vec) + brep_trns = BRepBuilderAPI_Transform(brep, trns, copy) + brep_trns.Build() + return brep_trns.Shape() + +def normal_vector_from_plane(plane, vec_length=1): + ''' + returns a vector normal to the plane of length vec_length + @param plane: + ''' + trns = gp_Vec(plane.Axis().Direction()) + trns.Normalized() * vec_length + return trns + +#=============================================================================== +# FIX +#=============================================================================== +def fix_tolerance( shape, tolerance=TOLERANCE): + from OCC.ShapeFix import ShapeFix_ShapeTolerance + ShapeFix_ShapeTolerance().SetTolerance(shape, tolerance) + +def fix_continuity(edge, continuity=1): + from OCC.ShapeUpgrade import ShapeUpgrade_ShapeDivideContinuity + su = ShapeUpgrade_ShapeDivideContinuity(edge) + su.SetBoundaryCriterion(eval('GeomAbs_C'+str(continuity))) + su.Perform() + st = ShapeToTopology() + te = st(su.Result()) + return te + +def resample_curve_with_uniform_deflection(curve, deflection=0.5, degreeMin=3, degreeMax=8, continuity=GeomAbs_C2, tolerance=1e-4): + ''' + fits a bspline through the samples on `curve` + @param curve: TopoDS_Wire, TopoDS_Edge, curve + @param n_samples: + ''' + from OCC.GCPnts import GCPnts_UniformDeflection + crv = to_adaptor_3d(curve) + defl = GCPnts_UniformDeflection(crv, deflection) + with assert_isdone(defl, 'failed to compute UniformDeflection'): + print 'number of points:', defl.NbPoints() + sampled_pnts = [defl.Value(i) for i in xrange(1, defl.NbPoints())] + resampled_curve = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(sampled_pnts), degreeMin, degreeMax, continuity, tolerance) + return resampled_curve.Curve().GetObject() + +#=============================================================================== +# global properties +#=============================================================================== +class GpropsFromShape(object): + def __init__(self, shape, tolerance=1e-5): + from OCC.BRepGProp import BRepGProp + self.shape = shape + self.bgprop = BRepGProp() + self.tolerance = tolerance + + def volume(self): + '''returns the volume of a solid + ''' + prop = GProp_GProps() + error = self.bgprop.VolumeProperties(self.shape, prop, self.tolerance) + return prop + + def surface(self): + '''returns the area of a surface + ''' + prop = GProp_GProps() + error = self.bgprop.SurfaceProperties(self.shape, prop, self.tolerance) + return prop + + def linear(self): + '''returns the length of a wire or edge + ''' + prop = GProp_GProps() + error = self.bgprop.LinearProperties(self.shape, prop ) + return prop + +def curve_length(crv): + ''' + get the length from a TopoDS_Edge or TopoDS_Wire + ''' + assert isinstance(crv,(TopoDS_Wire, TopoDS_Edge)), 'either a wire or edge...' + gprop = GpropsFromShape(crv) + return gprop.linear().Mass() + + +#======================================================================= +# Distance +#======================================================================= + +def minimum_distance(shp1, shp2): + ''' + compute minimum distance between 2 BREP's + @param shp1: any TopoDS_* + @param shp2: any TopoDS_* + + @return: minimum distance, + minimum distance points on shp1 + minimum distance points on shp2 + ''' + from OCC.BRepExtrema import BRepExtrema_DistShapeShape + bdss = BRepExtrema_DistShapeShape(shp1, shp2) + bdss.Perform() + with assert_isdone(bdss, 'failed computing minimum distances'): + min_dist = bdss.Value() + min_dist_shp1, min_dist_shp2 = [],[] + for i in range(1,bdss.NbSolution()+1): + min_dist_shp1.append(bdss.PointOnShape1(i)) + min_dist_shp2.append(bdss.PointOnShape2(i)) + return min_dist, min_dist_shp1, min_dist_shp2 + +def vertex2pnt(vertex): + '''returns a gp_Pnt from a TopoDS_Vertex + ''' + from OCC.BRep import BRep_Tool + return BRep_Tool.Pnt(vertex) + +def to_adaptor_3d(curveType): + ''' + abstract curve like type into an adaptor3d + @param curveType: + ''' + from OCC.BRepAdaptor import BRepAdaptor_CompCurve + from OCC.GeomAdaptor import GeomAdaptor_Curve + from OCC.Geom import Geom_Curve + if isinstance(curveType, TopoDS_Wire): + return BRepAdaptor_CompCurve(curveType) + elif isinstance(curveType, TopoDS_Edge): + return BRepAdaptor_Curve(curveType) + elif issubclass(curveType.__class__, Geom_Curve): + return GeomAdaptor_Curve(curveType.GetHandle()) + elif hasattr(curveType, 'GetObject'): + _crv = curveType.GetObject() + if issubclass(_crv.__class__, Geom_Curve): + return GeomAdaptor_Curve(curveType) + else: + raise TypeError('allowed types are Wire, Edge or a subclass of Geom_Curve\nGot a %s' % (curveType.__class__)) + +def project_point_on_curve(crv, pnt): + if isinstance(crv, TopoDS_Shape): + # get the curve handle... + crv = adapt_edge_to_curve(crv).Curve().Curve() + else: + raise NotImplementedError('expected a TopoDS_Edge...') + from OCC.GeomAPI import GeomAPI_ProjectPointOnCurve + rrr = GeomAPI_ProjectPointOnCurve(pnt, crv) + return rrr.LowerDistanceParameter(), rrr.NearestPoint() + +def project_point_on_plane( plane, point ): + ''' + project point on plane + @param plane: Geom_Plane + @param point: gp_Pnt + ''' + from OCC.ProjLib import ProjLib + pl = plane.Pln() + ppp = ProjLib() + aa, bb = ppp.Project(pl, point).Coord() + point = plane.Value(aa,bb) + return point + +def wire_to_curve(wire, tolerance=TOLERANCE, order=GeomAbs_C2, max_segment=200, max_order=12): + ''' + a wire can consist of many edges. + these edges are merged given a tolerance and a curve + @param wire: + ''' + adap = BRepAdaptor_CompCurve(wire) + hadap = BRepAdaptor_HCompCurve(adap) + from OCC.Approx import Approx_Curve3d + approx = Approx_Curve3d(hadap.GetHandle(), tolerance, order, max_segment, max_order) + with assert_isdone(approx, 'not able to compute approximation from wire'): + return approx.Curve().GetObject() + +def adapt_edge_to_curve(edg): + ''' + returns a curve adaptor from an edge + @param edg: TopoDS_Edge + ''' + return BRepAdaptor_Curve(edg) + +def adapt_edge_to_hcurve(edg): + c = BRepAdaptor_HCurve() + c.ChangeCurve().Initialize(edg) + return c + diff --git a/src/addons/Utils/Construct.py b/src/addons/Utils/Construct.py index fbcb86d23..315cf066b 100644 --- a/src/addons/Utils/Construct.py +++ b/src/addons/Utils/Construct.py @@ -26,35 +26,26 @@ from __future__ import with_statement # wrapped modules -import warnings from OCC.BRep import BRep_Tool -from OCC.BRepAlgo import BRepAlgo_Cut, BRepAlgo_Fuse from OCC.BRepOffset import BRepOffset_Skin +from OCC.Geom import Geom_TrimmedCurve from OCC.GeomConvert import GeomConvert_ApproxCurve from OCC.GeomLProp import * -from OCC.ShapeFix import * -from OCC.BRepOffsetAPI import * from OCC.BRepBuilderAPI import * -from OCC.BRepAlgoAPI import BRepAlgoAPI_Cut -from OCC.BRepAlgoAPI import BRepAlgoAPI_Fuse from OCC.BRepPrimAPI import * from OCC.GeomAbs import * from OCC.TopAbs import * from OCC.TopoDS import * from OCC.gp import * -from OCC.BRepFill import * -from OCC.GeomPlate import * -from OCC.BRepAdaptor import * -from OCC.GeomFill import * -from OCC.TopTools import * -from OCC.Geom import * # high level from OCC.Utils.Common import * from OCC.Utils.Context import assert_isdone -from OCC.KBE.types_lut import ShapeToTopology +from OCC.KBE.types_lut import shape_lut, curve_lut, surface_lut, topo_lut from functools import wraps +import warnings, operator, math +from src.addons.Utils.Common import to_tcol_ EPSILON = TOLERANCE = 1e-6 ST = ShapeToTopology() @@ -92,6 +83,10 @@ def gp_Pnt_set_state(self, state): ''' self.__init__(*state) +def gp_Pnt_equal(self, other): + print 'jelle contains!!!' + return self.IsEqual(other, TOLERANCE) + def gp_pnt_print(self): return '< gp_Pnt: {0}, {1}, {2} >'.format(*self.Coord()) @@ -100,6 +95,43 @@ def gp_vec_print(self): magn = self.Magnitude() return '< gp_Vec: {0}, {1}, {2}, magnitude: {3} >'.format(x,y,z, magn) +def gp_ax1_print(self): + pX, pY, pZ = self.Location().Coord() + dX, dY, dZ = self.Direction().Coord() + return "< gp_Ax1: location: {pX}, {pY}, {pZ}, direction: {dX}, {dY}, {dZ} >".format(**vars()) + +def gp_trsf_print(self): + _f = lambda x: [self.Value(x,i) for i in range(1,5)] + a,b,c,d = _f(1) + e,f,g,h = _f(2) + i,j,k,l = _f(3) + return "< gp_Trsf:\n {a:.3f}, {b:.3f}, {c:.3f}, {d:.3f}\n {e:.3f}, {f:.3f}, {g:.3f}, {h:.3f}\n {i:.3f}, {j:.3f}, {k:.3f}, {l:.3f} >".format(**vars()) + +def gp_quat_print(self): + w,x,y,z = self.W(), self.X(), self.Y(), self.Z() + vec = gp_Vec() + angle = math.degrees(self.GetVectorAndAngle(vec)) + return "< gp_Quaternion: w:{w}, x:{x}, y:{y}, z:{z} >\nvector:{vec} angle:{angle}".format(**vars()) + +def _apply(pnt, other, _operator): + if isinstance(other, gp_Pnt): + return gp_Pnt(*map(lambda x: _operator(*x), zip(pnt.Coord(), other.Coord()))) + else: + return gp_Pnt(*map(lambda x: _operator(x, other), pnt.Coord())) + +def gp_pnt_add(self, other): + return _apply(self, other, operator.add) + +def gp_pnt_sub(self, other): + return _apply(self, other, operator.sub) + +def gp_pnt_mul(self, other): + return _apply(self, other, operator.mul) + +def gp_pnt_div(self, other): + return _apply(self, other, operator.div) + + # easier conversion between data types gp_Vec.as_pnt = vector_to_point gp_Pnt.as_vec = point_to_vector @@ -111,11 +143,24 @@ def gp_vec_print(self): gp_Pnt.__setstate__ = gp_Pnt_set_state gp_Vec.__getstate__ = gp_Pnt_get_state gp_Vec.__setstate__ = gp_Pnt_set_state +# equality, not identity comparison +gp_Pnt.__eq__ = gp_Pnt_equal # print gp_Pnt() should return something informative... gp_Vec.__repr__ = gp_vec_print gp_Vec.__str__ = gp_vec_print gp_Pnt.__repr__ = gp_pnt_print gp_Pnt.__str__ = gp_pnt_print +gp_Ax1.__repr__ = gp_ax1_print +gp_Ax1.__str__ = gp_ax1_print +gp_Trsf.__repr__ = gp_trsf_print +gp_Trsf.__str__ = gp_trsf_print +gp_Quaternion.__repr__ = gp_quat_print +gp_Quaternion.__str__ = gp_quat_print +#gp_Pnt.__eq__ = gp_equal +gp_Pnt.__add__ = gp_pnt_add +gp_Pnt.__sub__ = gp_pnt_sub +gp_Pnt.__mul__ = gp_pnt_mul +gp_Pnt.__div__ = gp_pnt_div #=============================================================================== # ---TOPOLOGY--- @@ -146,6 +191,14 @@ def make_face(*args): face.Delete() return result +@wraps(BRepBuilderAPI_MakeEdge2d) +def make_edge2d(*args): + edge = BRepBuilderAPI_MakeEdge2d(*args) + with assert_isdone(edge, 'failed to produce edge'): + result = edge.Edge() + edge.Delete() + return result + @wraps(BRepBuilderAPI_MakeEdge) def make_edge(*args): edge = BRepBuilderAPI_MakeEdge(*args) @@ -167,6 +220,7 @@ def make_wire(*args): # if we get an iterable, than add all edges to wire builder if isinstance(args[0], list) or isinstance(args[0], tuple): wire = BRepBuilderAPI_MakeWire() + #from OCC.TopTools import TopTools_ListOfShape for i in args[0]: wire.Add(i) wire.Build() @@ -236,6 +290,7 @@ def make_evolved(spine, profile): return evol.Evolved() def make_pipe(spine, profile): + from OCC.BRepOffsetAPI import BRepOffsetAPI_MakePipe pipe = BRepOffsetAPI_MakePipe(spine, profile) with assert_isdone(pipe, 'failed building pipe'): pipe.Build() @@ -254,13 +309,18 @@ def make_prism_shell(profile, vec): ''' makes a finite prism ''' + from OCC.BRepOffsetAPI import BRepOffsetAPI_MakePipeShell return BRepOffsetAPI_MakePipeShell() -def make_offset_shape(shapeToOffset, offsetDistance, tolerance=TOLERANCE, offsetMode=BRepOffset_Skin, intersection=False, selfintersection=False, joinType=GeomAbs_Arc): +def make_offset_shape(shapeToOffset, offsetDistance, tolerance=TOLERANCE, + offsetMode=BRepOffset_Skin, intersection=False, + selfintersection=False, joinType=GeomAbs_Arc): + # TODO: refactor assert_isdone ''' builds an offsetted shell from a shape construct an offsetted version of the shape ''' + from OCC.BRepOffsetAPI import BRepOffsetAPI_MakeOffsetShape try: offset = BRepOffsetAPI_MakeOffsetShape(shapeToOffset, offsetDistance, @@ -270,11 +330,15 @@ def make_offset_shape(shapeToOffset, offsetDistance, tolerance=TOLERANCE, offset selfintersection, joinType ) - return offset.Shape() + if offset.IsDone(): + return offset.Shape() + else: + return None except RuntimeError('failed to offset shape'): return None def make_offset(wire_or_face, offsetDistance, altitude=0, joinType=GeomAbs_Arc): + # TODO: refactor assert_isdone ''' builds a offsetted wire or face from a wire or face construct an offsetted version of the shape @@ -289,12 +353,16 @@ def make_offset(wire_or_face, offsetDistance, altitude=0, joinType=GeomAbs_Arc): note: a shape that has a negative offsetDistance will return a sharp corner ''' + from OCC.BRepOffsetAPI import BRepOffsetAPI_MakeOffset _joints = [ GeomAbs_Arc, GeomAbs_Tangent, GeomAbs_Intersection ] assert joinType in _joints, '%s is not one of %s' ( joinType, _joints) try: offset = BRepOffsetAPI_MakeOffset(wire_or_face,joinType) offset.Perform(offsetDistance, altitude) - return ST(offset.Shape()) + if offset.IsDone(): + return ST(offset.Shape()) + else: + return None except RuntimeError('failed to offset shape'): return None @@ -302,15 +370,18 @@ def make_draft(profile, vec): ''' makes a finite prism ''' + from OCC.BRepOffsetAPI import BRepOffsetAPI_MakeDraft return BRepOffsetAPI_MakeDraft() def make_filling(profile, vec): ''' makes a n-sided patch from constraints ''' + from OCC.BRepOffsetAPI import BRepOffsetAPI_MakeFilling return BRepOffsetAPI_MakeFilling() -def make_loft(elements, ruled=False, tolerance=TOLERANCE): +def make_loft(elements, ruled=False, tolerance=TOLERANCE, continuity=GeomAbs_C2, check_compatibility=True): + from OCC.BRepOffsetAPI import BRepOffsetAPI_ThruSections sections = BRepOffsetAPI_ThruSections(False, ruled, tolerance) for i in elements: if isinstance(i, TopoDS_Wire): @@ -319,13 +390,19 @@ def make_loft(elements, ruled=False, tolerance=TOLERANCE): sections.AddVertex(i) else: raise TypeError('elements is a list of TopoDS_Wire or TopoDS_Vertex, found a %s fool' % ( i.__class__ )) - sections.CheckCompatibility(True) + + sections.CheckCompatibility(check_compatibility) + sections.SetContinuity(continuity) sections.Build() with assert_isdone(sections, 'failed lofting'): te = ShapeToTopology() loft = te(sections.Shape()) return loft +def make_ruled(edgeA, edgeB): + from OCC.BRepFill import BRepFill_Face + return BRepFill_Face(edgeA, edgeB) + #=============================================================================== # ---CONVENIENCE--- #=============================================================================== @@ -352,8 +429,33 @@ def make_plane(center=gp_Pnt(0,0,0), return face +def make_oriented_box(v_corner, v_x, v_y, v_z): + """ + produces an oriented box + oriented meaning here that the x,y,z axis do not have to be cartesian aligned + + :param v_corner: the lower corner + :param v_x: gp_Vec that describes the X-axis + :param v_y: gp_Vec that describes the Y-axis + :param v_z: gp_Vec that describes the Z-axis + :return: TopoDS_Solid + """ + from OCC.BRepOffsetAPI import BRepOffsetAPI_MakePipe + verts = map(lambda x: x.as_pnt(), [v_corner, v_corner+v_x, v_corner+v_x+v_y, v_corner+v_y]) + p = make_polygon(verts, closed=True) + li = make_line(v_corner.as_pnt(), (v_corner+v_z).as_pnt()) + ooo = BRepOffsetAPI_MakePipe(p,li) + ooo.Build() + shp = ooo.Shape() + + bottom = make_face(p) + top = translate_topods_from_vector(bottom, v_z, True) + oriented_bbox = make_solid(sew_shapes([bottom, shp, top])) + return oriented_bbox + + @wraps(BRepPrimAPI_MakeBox) -def make_cube(*args): +def make_box(*args): box = BRepPrimAPI_MakeBox(*args) box.Build() with assert_isdone(box, 'failed to built a cube...'): @@ -401,25 +503,31 @@ def make_n_sided(edges, points, continuity=GeomAbs_C0): :param continuity: GeomAbs_0, 1, 2 :return: TopoDS_Face """ - n_sided = BRepFill_Filling() - n_sided.SetApproxParam(6, 40) - n_sided.SetResolParam(3, 20, 20, False) + from OCC.BRepFill import BRepFill_Filling + n_sided = BRepFill_Filling(NbIter=6) + #n_sided.SetApproxParam( 6, 40) + #n_sided.SetResolParam( 3, 20, 20, False) for edg in edges: n_sided.Add(edg, continuity) for pt in points: n_sided.Add(pt) n_sided.Build() - face = n_sided.Face() + #if n_sided.IsDone(): + face = n_sided.Face() return face - + def make_n_sections(edges): + from OCC.TopTools import TopTools_SequenceOfShape + from OCC.BRepFill import BRepFill_NSections seq = TopTools_SequenceOfShape() for i in edges: seq.Append(i) n_sec = BRepFill_NSections(seq) + return n_sec def make_coons(edges): + from OCC.GeomFill import GeomFill_BSplineCurves, GeomFill_StretchStyle bt = BRep_Tool() if len(edges) == 4: spl1, spl2, spl3, spl4 = edges #[curve_to_bspline(bt.Curve(i)[0]) for i in edges] @@ -436,10 +544,11 @@ def make_coons(edges): def make_constrained_surface_from_edges(edges): ''' - DOESNT RESPECT BOUNDARIES - ''' + from OCC.BRepAdaptor import BRepAdaptor_HCurve + from OCC.GeomPlate import GeomPlate_MakeApprox, GeomPlate_BuildPlateSurface + from OCC.BRepFill import BRepFill_CurveConstraint bpSrf = GeomPlate_BuildPlateSurface(3,15,2) for edg in edges: c = BRepAdaptor_HCurve() @@ -480,7 +589,7 @@ def sew_shapes( shapes, tolerance=0.001 ): # sew = BRepBuilderAPI_Sewing(tolerance, True, True, True, False) # sew = BRepBuilderAPI_Sewing(1e-3, True, False, False, False) sew = BRepBuilderAPI_Sewing(tolerance) - sew.SetFloatingEdgesMode(True) + # sew.SetFloatingEdgesMode(True) for shp in shapes: if isinstance(shp, list): for i in shp: @@ -492,10 +601,7 @@ def sew_shapes( shapes, tolerance=0.001 ): print 'n deleted faces:',sew.NbDeletedFaces() print 'n free edges',sew.NbFreeEdges() print 'n multiple edges:',sew.NbMultipleEdges() - - result = sew.SewedShape() -# ??? -# sew.Delete() + result = ShapeToTopology()(sew.SewedShape()) return result #=============================================================================== @@ -503,6 +609,7 @@ def sew_shapes( shapes, tolerance=0.001 ): #=============================================================================== def boolean_cut(shapeToCutFrom, cuttingShape): + from OCC.BRepAlgoAPI import BRepAlgoAPI_Cut try: cut = BRepAlgoAPI_Cut(shapeToCutFrom, cuttingShape) print 'can work?', cut.BuilderCanWork() @@ -527,6 +634,7 @@ def boolean_cut(shapeToCutFrom, cuttingShape): return shapeToCutFrom def boolean_cut_old(shapeToCutFrom, cuttingShape): + from OCC.BRepAlgo import BRepAlgo_Cut cut = BRepAlgo_Cut(shapeToCutFrom, cuttingShape) #cut.RefineEdges() #cut.FuseEdges() @@ -534,6 +642,7 @@ def boolean_cut_old(shapeToCutFrom, cuttingShape): return shp def boolean_fuse(shapeToCutFrom, joiningShape): + from OCC.BRepAlgoAPI import BRepAlgoAPI_Fuse join = BRepAlgoAPI_Fuse(shapeToCutFrom, joiningShape) join.RefineEdges() join.FuseEdges() @@ -542,15 +651,35 @@ def boolean_fuse(shapeToCutFrom, joiningShape): return shape def boolean_fuse_old(shapeToCutFrom, joiningShape): + from OCC.BRepAlgo import BRepAlgo_Fuse join = BRepAlgo_Fuse(shapeToCutFrom, joiningShape) shape = join.Shape() join.Delete() return shape +def splitter(shape, profile): + '''split a *shape* using a *profile* + :returns the splitted shape + ''' + try: + from OCC.GEOMAlgo import GEOMAlgo_Splitter + except ImportError: + msg = "GEOM wrapper is necesary to access advanced constructs" + warnings.warn(msg) + return None + splitter = GEOMAlgo_Splitter() + splitter.AddShape(shape) + splitter.AddTool(profile) + splitter.Perform() + splitter_shape = splitter.Shape() + return splitter_shape + + def trim_wire(wire, shapeLimit1, shapeLimit2, periodic=False): '''return the trimmed wire that lies between `shapeLimit1` and `shapeLimit2` returns TopoDS_Edge ''' + adap = to_adaptor_3d(wire) bspl = adap.BSpline() if periodic: @@ -571,6 +700,7 @@ def trim_wire(wire, shapeLimit1, shapeLimit2, periodic=False): #=============================================================================== def fix_shape(shp, tolerance=1e-3): + from OCC.ShapeFix import ShapeFix_Shape te = ShapeToTopology() fix = ShapeFix_Shape(shp) fix.SetFixFreeShellMode(True) @@ -581,6 +711,7 @@ def fix_shape(shp, tolerance=1e-3): return fix.Shape() def fix_face(shp, tolerance=1e-3): + from OCC.ShapeFix import ShapeFix_Face fix = ShapeFix_Face(shp) fix.SetMaxTolerance(tolerance) fix.Perform() @@ -596,12 +727,14 @@ def translate_topods_from_vector(brep_or_iterable, vec, copy=False): @param vec: the vector defining the translation @param copy: copies to brep if True ''' + from OCC.KBE.types_lut import ShapeToTopology + st = ShapeToTopology() trns = gp_Trsf() trns.SetTranslation(vec) if issubclass(brep_or_iterable.__class__, TopoDS_Shape): brep_trns = BRepBuilderAPI_Transform(brep_or_iterable, trns, copy) brep_trns.Build() - return brep_trns.Shape() + return st(brep_trns.Shape()) else: return [translate_topods_from_vector(brep_or_iterable, vec, copy) for i in brep_or_iterable] @@ -691,15 +824,56 @@ def face_normal(face): return norm def face_from_plane(_geom_plane, lowerLimit=-1000, upperLimit=1000): + from OCC.Geom import Geom_RectangularTrimmedSurface _trim_plane = make_face( Geom_RectangularTrimmedSurface(_geom_plane.GetHandle(), lowerLimit, upperLimit, lowerLimit, upperLimit).GetHandle() ) return _trim_plane -def find_plane_from_shape(shape, tolerance=TOLERANCE): +def find_plane_from_shape(shape, tolerance=-1): try: - return BRepBuilderAPI_FindPlane(shape, tolerance).Plane().GetObject() + fpl = BRepBuilderAPI_FindPlane(shape, tolerance) + if fpl.Found(): + return fpl.Plane().GetObject() + else: + return None except: raise AssertionError('couldnt find plane in %s' % (shape)) +def fit_plane_through_face_vertices(_face): + """ + :param _face: OCC.KBE.face.Face instance + :return: Geom_Plane + """ + from OCC.GeomPlate import GeomPlate_BuildAveragePlane + from OCC.Utils.Topology import Topo + + + uvs_from_vertices = [_face.project_vertex(vertex2pnt(i)) for i in Topo(_face).vertices()] + normals = [gp_Vec(_face.DiffGeom.normal(*uv[0])) for uv in uvs_from_vertices] + points = [i[1] for i in uvs_from_vertices] + + NORMALS = TColgp_SequenceOfVec() + [NORMALS.Append(i) for i in normals] + POINTS = to_tcol_(points, TColgp_HArray1OfPnt) + + pl = GeomPlate_BuildAveragePlane(NORMALS, POINTS).Plane().GetObject() + vec = gp_Vec(pl.Location(), _face.GlobalProperties.centre()) + pt = (pl.Location().as_vec() + vec).as_pnt() + pl.SetLocation(pt) + return pl + +def project_edge_onto_plane(edg, plane): + """ + p'bably BRepOffsetAPI_NormalProjection would be a good option too, it expects + + :param edg: kbe.edge.Edge + :param plane: Geom_Plane + :return: TopoDS_Edge projected on the plane + """ + from OCC.GeomProjLib import GeomProjLib_ProjectOnPlane + proj = GeomProjLib_ProjectOnPlane(edg.adaptor.Curve().Curve(), plane.GetHandle(), plane.Axis().Direction(), 1 ) + return make_edge(proj) + + def curve_to_bspline(crv_handle, tolerance=TOLERANCE, continuity=GeomAbs_C1, sections=300, degree=12): approx_curve = GeomConvert_ApproxCurve(crv_handle, tolerance, continuity, sections, degree) with assert_isdone(approx_curve, 'could not compute bspline from curve'): @@ -714,7 +888,43 @@ def compound(topo): comp = TopoDS_Compound() bd.MakeCompound(comp) for i in topo: - print i bd.Add(comp,i) return comp +def geodesic_path(pntA, pntB, edgA, edgB, kbe_face, n_segments=20, _tolerance=0.1, n_iter=20): + """ + :param pntA: point to start from + :param pntB: point to move towards + :param edgA: edge to start from + :param edgB: edge to move towards + :param kbe_face: kbe.face.Face on which `edgA` and `edgB` lie + :param n_segments: the number of segments the geodesic is built from + :param _tolerance: tolerance when the geodesic is converged + :param n_iter: maximum number of iterations + :return: TopoDS_Edge + """ + from OCC.Utils.Common import smooth_pnts + uvA, srf_pnt_A = kbe_face.project_vertex(pntA) + uvB, srf_pnt_B = kbe_face.project_vertex(pntB) + + path = [] + for i in range(n_segments): + t = i / float(n_segments) + u = uvA[0] + t*(uvB[0] - uvA[0]) + v = uvA[1] + t*(uvB[1] - uvA[1]) + path.append(kbe_face.parameter_to_point(u,v)) + + project_pnts = lambda x: [kbe_face.project_vertex(i)[1] for i in x] + poly_length = lambda x: sum([x[i].Distance(x[i+1]) for i in range(len(x)-1)]) / len(x) + + length = poly_length(path) + + n = 0 + while True: + path = smooth_pnts(path) + path = project_pnts(path) + newlength = poly_length(path) + if abs(newlength-length) < _tolerance or n == n_iter: + crv = points_to_bspline(path) + return make_edge(crv) + n+=1 From db0a01fdd5551827268de8c5f3fb13a37c83d5be Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 15:36:26 +0200 Subject: [PATCH 08/29] i really am not very good at merging... sigh... what is really worrying me though that the earlier parameters in animation.py are really ORDERS OF MAGNITUDE from something that works well on my computer lets _please_ compare our different timings, it looks like this is indicating a serious regression... on my machine it takes: 200 rotations took 3.33342504501 200 rotations took 3.34982919693 which _really_ are absurdly low values.... lets looks into that! this is pretty worrying... --- src/addons/Display/OCCViewer.py | 8 +++++++- src/addons/Display/qtDisplay.py | 5 ++++- src/addons/Utils/Construct.py | 3 ++- src/examples/Animation/animation.py | 22 +++++++++++++++------- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/addons/Display/OCCViewer.py b/src/addons/Display/OCCViewer.py index 06dfc08fb..7b750e1fa 100644 --- a/src/addons/Display/OCCViewer.py +++ b/src/addons/Display/OCCViewer.py @@ -364,7 +364,13 @@ def Pan(self,Dx,Dy): def SetSelectionMode(self, mode=None): self.Context.CloseAllContexts() self.Context.OpenLocalContext() - self.Context.ActivateStandardMode(mode) + topo_level = modes.next() + print 'current topology selection mode:', topo_lut[topo_level] + if mode is None: + self.Context.ActivateStandardMode(topo_level) + else: + self.Context.ActivateStandardMode(mode) + self.Context.UpdateSelected() def SetSelectionModeShape(self): self.Context.CloseAllContexts() diff --git a/src/addons/Display/qtDisplay.py b/src/addons/Display/qtDisplay.py index 802a24cff..51c24da15 100644 --- a/src/addons/Display/qtDisplay.py +++ b/src/addons/Display/qtDisplay.py @@ -43,7 +43,9 @@ def __init__(self, parent = None): self._inited = False self.setMouseTracking(True) #enable Mouse Tracking self.setFocusPolicy(QtCore.Qt.WheelFocus)#Strong focus + # On X11, setting this attribute will disable all double buffering self.setAttribute(QtCore.Qt.WA_PaintOnScreen) + # setting this flag implicitly disables double buffering for the widget self.setAttribute(QtCore.Qt.WA_NoSystemBackground) def GetHandle(self): @@ -81,6 +83,7 @@ def _SetupKeyMap(self): def set_shade_mode(): self._display.DisableAntiAliasing() self._display.SetModeShaded() + self._key_map = { ord('W'): self._display.SetModeWireFrame, ord('S'): set_shade_mode, @@ -91,7 +94,7 @@ def set_shade_mode(): ord('F'): self._display.FitAll, #ord('F'): self._display.ExportToImage("essai.BMP"), #ord('F'): self._display.SetBackgroundImage("carrelage1.gif"), - ord('G'): self._display.SetSelectionModeVertex + ord('G'): self._display.SetSelectionMode } def keyPressEvent(self,event): diff --git a/src/addons/Utils/Construct.py b/src/addons/Utils/Construct.py index 315cf066b..5a725e449 100644 --- a/src/addons/Utils/Construct.py +++ b/src/addons/Utils/Construct.py @@ -45,7 +45,7 @@ from functools import wraps import warnings, operator, math -from src.addons.Utils.Common import to_tcol_ + EPSILON = TOLERANCE = 1e-6 ST = ShapeToTopology() @@ -845,6 +845,7 @@ def fit_plane_through_face_vertices(_face): """ from OCC.GeomPlate import GeomPlate_BuildAveragePlane from OCC.Utils.Topology import Topo + from OCC.Utils.Common import to_tcol uvs_from_vertices = [_face.project_vertex(vertex2pnt(i)) for i in Topo(_face).vertices()] diff --git a/src/examples/Animation/animation.py b/src/examples/Animation/animation.py index 8e6261352..d236877ec 100644 --- a/src/examples/Animation/animation.py +++ b/src/examples/Animation/animation.py @@ -22,14 +22,16 @@ from OCC.AIS import * from OCC.Display.SimpleGui import * -from OCC.Utils.Construct import make_cube +from OCC.Utils.Construct import make_box +import time + display, start_display, add_menu, add_function_to_menu = init_display() ais_boxshp=None def build_shape(): - boxshp = make_cube(50.,50.,50.) - ais_boxshp = display.DisplayShape(boxshp) + boxshp = make_box(50.,50.,50.) + ais_boxshp = display.DisplayShape(boxshp, update=True) return ais_boxshp def rotating_cube_1_axis(event=None): @@ -37,12 +39,15 @@ def rotating_cube_1_axis(event=None): Ax1 = gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1)) aCubeTrsf = gp_Trsf() angle = 0.0 - for i in range(2000): + tA = time.time() + n_rotations = 200 + for i in range(n_rotations): aCubeTrsf.SetRotation(Ax1,angle) aCubeToploc = TopLoc_Location(aCubeTrsf) display.Context.SetLocation(ais_boxshp,aCubeToploc) display.Context.UpdateCurrentViewer() - angle += 0.001 + angle += 0.1 + print "{0} rotations took {1}".format(n_rotations, time.time() - tA) def rotating_cube_2_axis(event=None): ais_boxshp = build_shape() @@ -52,13 +57,16 @@ def rotating_cube_2_axis(event=None): aCubeTrsf2 = gp_Trsf() angle = 0.0 angle2 = 0.0 - for i in range(2000): + tA = time.time() + n_rotations = 200 + for i in range(n_rotations): aCubeTrsf.SetRotation(Ax1,angle) aCubeTrsf2.SetRotation(Ax2,angle) aCubeToploc = TopLoc_Location(aCubeTrsf*aCubeTrsf2) display.Context.SetLocation(ais_boxshp,aCubeToploc) display.Context.UpdateCurrentViewer() - angle += 0.001 + angle += 0.1 + print "{0} rotations took {1}".format(n_rotations, time.time() - tA) if __name__ == '__main__': add_menu('animation') From 4e8b9064485cca845e506df8f3a7b225e83a4ca3 Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 15:42:44 +0200 Subject: [PATCH 09/29] fixed a OSX specific approach to loading the webgl scene in the browser, now using a python stdlib module, webbrowser --- src/addons/Display/WebGl/webgl_renderer.py | 6 +++++- src/examples/WebGl/webgl_geomplate.py | 24 ++++++---------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/addons/Display/WebGl/webgl_renderer.py b/src/addons/Display/WebGl/webgl_renderer.py index 43974f423..3fd0001a1 100644 --- a/src/addons/Display/WebGl/webgl_renderer.py +++ b/src/addons/Display/WebGl/webgl_renderer.py @@ -15,6 +15,7 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . +import webbrowser from OCC.Visualization import * from html_file import * from time import time @@ -42,7 +43,10 @@ def DisplayShape(self,shape): self.GenerateHTMLFile() print "done." print "Opening html output in the default webbrowser ..." - os.system('open %s'%self._html_filename) + # previous version us a os.system call to the "open" command + # but this is a platform (osx) specific solution + _path = "file:///{0}".format(os.path.join(os.getcwd(), self._html_filename)) + webbrowser.open_new_tab(_path) print "done." diff --git a/src/examples/WebGl/webgl_geomplate.py b/src/examples/WebGl/webgl_geomplate.py index 21895b471..3de876d53 100644 --- a/src/examples/WebGl/webgl_geomplate.py +++ b/src/examples/WebGl/webgl_geomplate.py @@ -15,25 +15,22 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . import os -from OCC.Utils.Construct import make_closed_polygon, make_n_sided, make_vertex, make_face, make_wire +import types +import sys +from OCC.Utils.Construct import make_closed_polygon, make_n_sided, make_vertex, make_face, make_wire from OCC.gp import * -from OCC.BRepBuilderAPI import * - from OCC.Utils.Topology import WireExplorer, Topo from OCC.BRepAdaptor import * from OCC.BRep import * from OCC.ShapeAnalysis import * from OCC.GeomLProp import * - -import types, sys, time - -from OCC.Utils.DataExchange.IGES import IGESImporter +from OCC.DataExchange.IGES import IGESImporter from OCC.BRepFill import * from OCC.GeomPlate import * -from OCC.GEOMAlgo import * - from OCC.Display.WebGl import webgl_renderer +from scipy.optimize import fsolve + def geom_plate(event=None): p1,p2,p3,p4,p5 = gp_Pnt(0,0,0),gp_Pnt(0,100,0),gp_Pnt(0,100,100),gp_Pnt(0,0,100),gp_Pnt(50,50,50) @@ -153,15 +150,6 @@ def solve(self): return self.plate -def solve_radius(event=None): - p1,p2,p3,p4,p5 = gp_Pnt(0,0,0),gp_Pnt(0,10,0),gp_Pnt(0,10,10),gp_Pnt(0,0,10),gp_Pnt(5,5,5) - poly = make_closed_polygon([p1,p2,p3,p4]) - for i in arange(0.1,3.,0.2).tolist(): - rcs = RadiusConstrainedSurface(display, poly, p5, i ) - face = rcs.solve() - print 'Goal: %s radius: %s' % ( i, rcs.curr_radius ) - time.sleep(0.5) - #=============================================================================== # #=============================================================================== From 488ba541f1b0bfc961fc79f7b854dc39526b0674 Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 17:13:29 +0200 Subject: [PATCH 10/29] minor changes to DYN --- src/addons/DYN/Context.py | 6 +++--- src/addons/DYN/Joints.py | 2 +- src/addons/DYN/Shape.py | 6 ++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/addons/DYN/Context.py b/src/addons/DYN/Context.py index eb49eca2f..eb058f98a 100644 --- a/src/addons/DYN/Context.py +++ b/src/addons/DYN/Context.py @@ -99,7 +99,8 @@ def set_display(self,display, yield_function=None): # Register a callback so that it's possible to move the view with the mouse # during the simulation. if yield_function is not None: - self.register_post_step_callback(yield_function) + if callable(yield_function): + self.register_post_step_callback(yield_function) def set_animation_frame_rate(self, frame_rate): ''' Define the frame rate, i.e. the number of frames displayed in one second of simulation. @@ -239,14 +240,13 @@ def start_open_loop(self, quick=False): # Not necessary by default : shape.store_cog_position([x,y,z]) # Then update the viewer to show new shapes position self._display.Context.UpdateCurrentViewer() - self._display.FitAll() # Increment time self._perform_callbacks() # Then increment time and loop simulation t += self._delta_t print 't',t - print 'redisply, disp init',MUST_REDISPLAY, self._DISPLAY_INITIALIZED + # increment the step index current_time_step_index += 1 # When the simulation is finished, draw cog positions for each shape diff --git a/src/addons/DYN/Joints.py b/src/addons/DYN/Joints.py index fd09854f4..37854f245 100644 --- a/src/addons/DYN/Joints.py +++ b/src/addons/DYN/Joints.py @@ -42,7 +42,7 @@ class DynamicHingeJoint(ode.HingeJoint): """ def _init__(self,dyn_context): self.dyn_context = dyn_context - ode.HingeJoint.__init__(self,*kargs) + ode.HingeJoint.__init__(self) def set_anchor(self,gp_point_center): ''' Set the anchor of the ball joint diff --git a/src/addons/DYN/Shape.py b/src/addons/DYN/Shape.py index ee5ef6d6d..4ca4d3eda 100644 --- a/src/addons/DYN/Shape.py +++ b/src/addons/DYN/Shape.py @@ -79,8 +79,7 @@ def enable_collision_detection(self): self._space = self._parent_context.get_collision_space() def use_bounding_box(self): - bbox = get_boundingbox(self._shape, EPSILON) - xmin,ymin,zmin, xmax,ymax,zmax = bbox.Get() + xmin,ymin,zmin, xmax,ymax,zmax = get_boundingbox(self._shape, EPSILON) dx,dy,dz = xmax-xmin, ymax-ymin, zmax-zmin self._collision_geometry = ode.GeomBox(self._space, lengths=(dx,dy,dz)) self._collision_geometry.setBody(self) @@ -91,8 +90,7 @@ def use_sphere(self): if the TopoDS_Shape is a sphere, then the radius of the ode.GeomSphere will be the radius of the sphere ''' - bbox = get_boundingbox(self._shape, EPSILON) - xmin,ymin,zmin, xmax,ymax,zmax = bbox.Get() + xmin,ymin,zmin, xmax,ymax,zmax = get_boundingbox(self._shape, EPSILON) dx,dy,dz = xmax-xmin, ymax-ymin, zmax-zmin r = (dx+dy+dz)/6.# /3 gives the mean diameter, so divide by 2 for the radius self._collision_geometry = ode.GeomSphere(self._space, radius = r) From 077f1a150736ef5f5b1c5c6ce18966b42baf4799 Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 17:15:22 +0200 Subject: [PATCH 11/29] checking the examples, making minor fixes, those related to DisplayShape and SimpleGui basically --- .../Step3_Boolean/Step3_2.py | 28 +- src/addons/Display/OCCViewer.py | 2 +- src/addons/Display/qtDisplay.py | 14 +- src/examples/CADViewer/CADViewerMDI.py | 8 +- src/examples/Concurrency/parallel_slicer.py | 19 +- .../DataExchange/export_multi_to_iges.py | 2 +- .../DataExchange/export_multi_to_step.py | 2 +- ...export_multi_to_step_colors_layers_ocaf.py | 2 +- .../DataExchange/export_single_to_step.py | 2 +- src/examples/DataExchange/export_to_stl.py | 2 +- .../DataExchange/import_iges_multi.py | 6 +- .../DataExchange/import_iges_single.py | 6 +- .../DataExchange/import_step_multi.py | 2 +- .../DataExchange/import_step_single.py | 2 +- src/examples/DataExchange/import_stl.py | 2 +- src/examples/Dimensions/dimensions.py | 1 - src/examples/Display/customize_linewidth.py | 3 +- src/examples/Display/display_quality.py | 11 +- src/examples/Display/enviroment_mapping.py | 2 +- src/examples/Display/lightened_shape.py | 1 + src/examples/Display/material_face.py | 2 +- src/examples/Display/material_shape.py | 2 +- src/examples/Display/qt_demo.py | 3 +- src/examples/Display/wx_demo.py | 1 - src/examples/WebGl/shape.js | 5336 ++--------------- src/examples/WebGl/webgl_geomplate.py | 3 +- 26 files changed, 404 insertions(+), 5060 deletions(-) diff --git a/doc/tutorials/geometry_modeling_and_visualization/Step3_Boolean/Step3_2.py b/doc/tutorials/geometry_modeling_and_visualization/Step3_Boolean/Step3_2.py index 031b57c38..a0e517257 100755 --- a/doc/tutorials/geometry_modeling_and_visualization/Step3_Boolean/Step3_2.py +++ b/doc/tutorials/geometry_modeling_and_visualization/Step3_Boolean/Step3_2.py @@ -1,14 +1,14 @@ # ============================================================================= # Packages to import # ============================================================================= -import OCC.Display.SimpleGui import sys -from OCC import VERSION -from OCC.Display.wxDisplay import wxViewer3d -import OCC.gp -import OCC.BRepPrimAPI + +import OCC.Display.SimpleGui +import OCC.gp +import OCC.BRepPrimAPI import OCC.BRepAlgoAPI import scipy + # ============================================================================= # Some geometric functionality needed # ============================================================================= @@ -290,7 +290,7 @@ def draw_sphere_1(event=None): MySphere = sphere_from_vector_and_radius( PointZeroArray, Radius ) MySphereShape = MySphere.Shape() - display.DisplayColoredShape( MySphereShape , 'RED' ) + display.DisplayColoredShape( MySphereShape , 'RED' , update=True) def draw_sphere_2(event=None): # create sphere @@ -301,7 +301,7 @@ def draw_sphere_2(event=None): MySphere = sphere_from_vector_and_radius( MyPointAsArray, Radius / 1.2 ) MySphereShape = MySphere.Shape() - display.DisplayColoredShape( MySphereShape , 'YELLOW' ) + display.DisplayColoredShape( MySphereShape , 'YELLOW' , update=True) def draw_cylinder(event=None): # cylinder radius @@ -321,7 +321,7 @@ def draw_cylinder(event=None): Length, Radius ) MyCylinderShape = MyCylinder.Shape() - display.DisplayColoredShape( MyCylinderShape , 'BLUE' ) + display.DisplayColoredShape( MyCylinderShape , 'BLUE' , update=True) def draw_cone(event=None): # cone radius 1 @@ -345,7 +345,7 @@ def draw_cone(event=None): Radius2 ) MyConeShape = MyCone.Shape() - display.DisplayColoredShape( MyConeShape , 'ORANGE' ) + display.DisplayColoredShape( MyConeShape , 'ORANGE' , update=True) def draw_arrow(event=None): # Length of the Arrow @@ -373,7 +373,7 @@ def draw_arrow(event=None): LenghtOfArrowHead, RadiusOfArrowHead ) - display.DisplayColoredShape( MyArrowShape , 'BLACK' ) + display.DisplayColoredShape( MyArrowShape , 'BLACK' , update=True) def draw_fused_spheres(event=None): # clear the display @@ -399,7 +399,7 @@ def draw_fused_spheres(event=None): # Shape of combined spheres FusedSpheres = FusedSpheres.Shape() # Display - display.DisplayColoredShape( FusedSpheres , 'RED' ) + display.DisplayColoredShape( FusedSpheres , 'RED' , update=True) def draw_cutted_spheres_1(event=None): # clear the display @@ -425,7 +425,7 @@ def draw_cutted_spheres_1(event=None): # Shape of combined spheres CuttedSpheres = CuttedSpheres.Shape() # Display - display.DisplayColoredShape( CuttedSpheres , 'YELLOW' ) + display.DisplayColoredShape( CuttedSpheres , 'YELLOW' , update=True) def draw_cutted_spheres_2(event=None): # clear the display @@ -451,7 +451,7 @@ def draw_cutted_spheres_2(event=None): # Shape of combined spheres CuttedSpheres = CuttedSpheres.Shape() # Display - display.DisplayColoredShape( CuttedSpheres , 'BLUE' ) + display.DisplayColoredShape( CuttedSpheres , 'BLUE' , update=True) def draw_common_spheres(event=None): # clear the display @@ -477,7 +477,7 @@ def draw_common_spheres(event=None): # Shape of combined spheres CommonSpheres = CommonSpheres.Shape() # Display - display.DisplayColoredShape( CommonSpheres , 'GREEN' ) + display.DisplayColoredShape( CommonSpheres , 'GREEN', update=True ) def erase_all(event=None): diff --git a/src/addons/Display/OCCViewer.py b/src/addons/Display/OCCViewer.py index 7b750e1fa..5807dcdec 100644 --- a/src/addons/Display/OCCViewer.py +++ b/src/addons/Display/OCCViewer.py @@ -334,7 +334,7 @@ def DisplayColoredShape(self, shapes, color='YELLOW', update=False, ): else: raise ValueError('color should either be a string ( "BLUE" ) or a Quantity_Color(0.1, 0.8, 0.1) got %s' % color) - return self.DisplayShape(shapes, color=clr) + return self.DisplayShape(shapes, color=clr, update=update) def DisplayTriedron(self): diff --git a/src/addons/Display/qtDisplay.py b/src/addons/Display/qtDisplay.py index 51c24da15..f34391ffa 100644 --- a/src/addons/Display/qtDisplay.py +++ b/src/addons/Display/qtDisplay.py @@ -20,7 +20,7 @@ import os import sys -from PyQt4 import QtCore, QtGui +from PyQt4 import QtCore, QtGui, QtOpenGL import OCCViewer class point(object): @@ -34,11 +34,12 @@ def set(self,obj): self.x = obj.x() self.y = obj.y() -class qtBaseViewer(QtGui.QWidget): +class qtBaseViewer(QtOpenGL.QGLWidget): ''' The base Qt Widget for an OCC viewer ''' def __init__(self, parent = None): - QtGui.QWidget.__init__(self,parent) + # QtGui.QWidget.__init__(self,parent) + QtOpenGL.QGLWidget.__init__(self,parent) self._display = None self._inited = False self.setMouseTracking(True) #enable Mouse Tracking @@ -54,6 +55,13 @@ def GetHandle(self): def resizeEvent(self, event): if self._inited: self._display.OnResize() + + def initializeGL(self): + import ipdb; ipdb.set_trace() + + def paintGL(self): + import ipdb; ipdb.set_trace() + def paintEngine(self): return None diff --git a/src/examples/CADViewer/CADViewerMDI.py b/src/examples/CADViewer/CADViewerMDI.py index c1dc2a1d3..56d99919a 100644 --- a/src/examples/CADViewer/CADViewerMDI.py +++ b/src/examples/CADViewer/CADViewerMDI.py @@ -18,7 +18,13 @@ ##along with pythonOCC. If not, see . import sys, os -import wx + +try: + import wx +except ImportError: + print "wx is required for this example but was not found" + sys.exit(1) + from OCC.Display.wxDisplay import wxViewer3d from OCC import VERSION import time diff --git a/src/examples/Concurrency/parallel_slicer.py b/src/examples/Concurrency/parallel_slicer.py index 58f649fc4..aa6a82d08 100644 --- a/src/examples/Concurrency/parallel_slicer.py +++ b/src/examples/Concurrency/parallel_slicer.py @@ -1,24 +1,20 @@ from OCC.gp import * -from OCC.BRepPrimAPI import * from OCC.BRepAlgoAPI import * -from OCC.TopOpeBRepTool import * from OCC.BRepBuilderAPI import * -from OCC.Geom import * -from OCC.TopoDS import * from OCC.Display.SimpleGui import * display, start_display, add_menu, add_function_to_menu = init_display() -import time, numpy, os, pickle, sys +import time, numpy, os, sys if sys.version_info[:3] >= (2,6,0): import multiprocessing as processing else: import processing def get_brep(): - from OCC.Utils.DataExchange.utils import file_to_shape + from OCC.DataExchange.utils import file_to_shape pth = os.path.split(os.path.abspath(__file__))[0] - pth = os.path.abspath( os.path.join(pth, '../../../../data/_3dmodels/Pump_Bottom.brep') ) + pth = os.path.abspath( os.path.join(pth, '../../../data/_3dmodels/Pump_Bottom.brep') ) return file_to_shape(pth) def vectorized_slicer( li ): @@ -47,7 +43,7 @@ def run( n_procs, compare_by_number_of_processors=False ): shape = get_brep() display.DisplayShape(shape) - x_min, y_min, z_min, x_max, y_max, z_max = get_boundingbox(shape).Get() + x_min, y_min, z_min, x_max, y_max, z_max = get_boundingbox(shape) z_delta = abs( z_min - z_max ) # compute bounding box! @@ -108,10 +104,9 @@ def arguments(n_slices, n_procs): print '\n\n\n DONE SLICING ON %i CORES \n\n\n'%nprocs time.sleep(3) - for result_shp in _results: - print 'result_shp',result_shp - for i in result_shp: - display.DisplayShape(i, update=False) + for n, result_shp in enumerate(_results): + print 'displaying results from process {0}'.format(n) + display.DisplayShape(result_shp, update=True) # update viewer when all is added: display.Repaint() diff --git a/src/examples/DataExchange/export_multi_to_iges.py b/src/examples/DataExchange/export_multi_to_iges.py index 75d099dd1..2eea17721 100644 --- a/src/examples/DataExchange/export_multi_to_iges.py +++ b/src/examples/DataExchange/export_multi_to_iges.py @@ -15,7 +15,7 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from OCC.Utils.DataExchange.IGES import IGESExporter +from OCC.DataExchange.IGES import IGESExporter from OCC.BRepPrimAPI import * # First create a simple shape to export diff --git a/src/examples/DataExchange/export_multi_to_step.py b/src/examples/DataExchange/export_multi_to_step.py index d1a8c773a..0f5c42352 100644 --- a/src/examples/DataExchange/export_multi_to_step.py +++ b/src/examples/DataExchange/export_multi_to_step.py @@ -15,7 +15,7 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from OCC.Utils.DataExchange.STEP import STEPExporter +from OCC.DataExchange.STEP import STEPExporter from OCC.BRepPrimAPI import * # First create a simple shape to export diff --git a/src/examples/DataExchange/export_multi_to_step_colors_layers_ocaf.py b/src/examples/DataExchange/export_multi_to_step_colors_layers_ocaf.py index 6f87cdabc..a5196252e 100644 --- a/src/examples/DataExchange/export_multi_to_step_colors_layers_ocaf.py +++ b/src/examples/DataExchange/export_multi_to_step_colors_layers_ocaf.py @@ -15,7 +15,7 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from OCC.Utils.DataExchange.STEP import StepOCAF_Export +from OCC.DataExchange.STEP import StepOCAF_Export from OCC.BRepPrimAPI import * # First create a simple shape to export diff --git a/src/examples/DataExchange/export_single_to_step.py b/src/examples/DataExchange/export_single_to_step.py index a712c90b5..b1349d94f 100644 --- a/src/examples/DataExchange/export_single_to_step.py +++ b/src/examples/DataExchange/export_single_to_step.py @@ -15,7 +15,7 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from OCC.Utils.DataExchange.STEP import STEPExporter +from OCC.DataExchange.STEP import STEPExporter from OCC.BRepPrimAPI import * # First create a simple shape to export diff --git a/src/examples/DataExchange/export_to_stl.py b/src/examples/DataExchange/export_to_stl.py index 98cc6ed31..c0a7ae88f 100644 --- a/src/examples/DataExchange/export_to_stl.py +++ b/src/examples/DataExchange/export_to_stl.py @@ -15,7 +15,7 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from OCC.Utils.DataExchange.STL import STLExporter +from OCC.DataExchange.STL import STLExporter from OCC.BRepPrimAPI import * # First create a simple shape to export diff --git a/src/examples/DataExchange/import_iges_multi.py b/src/examples/DataExchange/import_iges_multi.py index 333ee2219..e16e189b3 100644 --- a/src/examples/DataExchange/import_iges_multi.py +++ b/src/examples/DataExchange/import_iges_multi.py @@ -15,13 +15,13 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from OCC.Utils.DataExchange.IGES import IGESImporter +from OCC.DataExchange.IGES import IGESImporter from OCC.Display.SimpleGui import * display, start_display, add_menu, add_function_to_menu = init_display() -my_iges_importer = IGESImporter("../../data/IGES/splines.igs") +my_iges_importer = IGESImporter("../data/IGES/splines.igs") my_iges_importer.read_file() the_shapes = my_iges_importer.get_shapes() -display.DisplayShape(the_shapes) +display.DisplayShape(the_shapes, update=True) start_display() diff --git a/src/examples/DataExchange/import_iges_single.py b/src/examples/DataExchange/import_iges_single.py index 2f13f975c..606879ea5 100644 --- a/src/examples/DataExchange/import_iges_single.py +++ b/src/examples/DataExchange/import_iges_single.py @@ -15,14 +15,14 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from OCC.Utils.DataExchange.IGES import IGESImporter +from OCC.DataExchange.IGES import IGESImporter from OCC.Display.SimpleGui import * display, start_display, add_menu, add_function_to_menu = init_display() -my_iges_importer = IGESImporter("../../data/IGES/splines.igs") +my_iges_importer = IGESImporter("../data/IGES/splines.igs") my_iges_importer.read_file() the_compound = my_iges_importer.get_compound() -display.DisplayShape(the_compound) +display.DisplayShape(the_compound, update=True) start_display() diff --git a/src/examples/DataExchange/import_step_multi.py b/src/examples/DataExchange/import_step_multi.py index 7adba9b70..6c899329c 100644 --- a/src/examples/DataExchange/import_step_multi.py +++ b/src/examples/DataExchange/import_step_multi.py @@ -15,7 +15,7 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from OCC.Utils.DataExchange.STEP import STEPImporter +from OCC.DataExchange.STEP import STEPImporter from OCC.Display.SimpleGui import * display, start_display, add_menu, add_function_to_menu = init_display() diff --git a/src/examples/DataExchange/import_step_single.py b/src/examples/DataExchange/import_step_single.py index 053e04351..fca1ccc64 100644 --- a/src/examples/DataExchange/import_step_single.py +++ b/src/examples/DataExchange/import_step_single.py @@ -15,7 +15,7 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from OCC.Utils.DataExchange.STEP import STEPImporter +from OCC.DataExchange.STEP import STEPImporter from OCC.Display.SimpleGui import * display, start_display, add_menu, add_function_to_menu = init_display() diff --git a/src/examples/DataExchange/import_stl.py b/src/examples/DataExchange/import_stl.py index d71a1a71c..f186b650f 100644 --- a/src/examples/DataExchange/import_stl.py +++ b/src/examples/DataExchange/import_stl.py @@ -15,7 +15,7 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from OCC.Utils.DataExchange.STL import STLImporter +from OCC.DataExchange.STL import STLImporter from OCC.Display.SimpleGui import * # open/parse STL file and get the resulting TopoDS_Shape instance diff --git a/src/examples/Dimensions/dimensions.py b/src/examples/Dimensions/dimensions.py index 28fc6fe85..061d03216 100644 --- a/src/examples/Dimensions/dimensions.py +++ b/src/examples/Dimensions/dimensions.py @@ -19,7 +19,6 @@ from OCC.gp import * from OCC.AIS import * -from OCC.TCollection import TCollection_ExtendedString from OCC.Utils.Construct import make_edge from OCC.Utils.Common import to_string diff --git a/src/examples/Display/customize_linewidth.py b/src/examples/Display/customize_linewidth.py index a215155a2..de8d5b45f 100644 --- a/src/examples/Display/customize_linewidth.py +++ b/src/examples/Display/customize_linewidth.py @@ -22,8 +22,7 @@ display, start_display, add_menu, add_function_to_menu = init_display() from OCC.AIS import * -from OCC.BRepPrimAPI import * -from OCC.Utils.Topology import Topo +from OCC.BRepPrimAPI import BRepPrimAPI_MakeBox # # Create a box diff --git a/src/examples/Display/display_quality.py b/src/examples/Display/display_quality.py index 4d07077e0..39d7b55f0 100644 --- a/src/examples/Display/display_quality.py +++ b/src/examples/Display/display_quality.py @@ -45,11 +45,12 @@ # # Improve quality by a factor 10 # -ais_context.SetDeviationCoefficient(dc/10.) -ais_context.SetDeviationAngle(da/10.) -ais_context.SetHLRDeviationCoefficient(dc_hlr/10.) -ais_context.SetHLRAngle(da_hlr/10.) -print "Quality display improved by a factor 10" +factor = 20.0 +ais_context.SetDeviationCoefficient(dc/factor) +ais_context.SetDeviationAngle(da/factor) +ais_context.SetHLRDeviationCoefficient(dc_hlr/factor) +ais_context.SetHLRAngle(da_hlr/factor) +print "Quality display improved by a factor {0}".format(factor) # # Displays a cylinder # diff --git a/src/examples/Display/enviroment_mapping.py b/src/examples/Display/enviroment_mapping.py index f0a612fd9..564ea9900 100644 --- a/src/examples/Display/enviroment_mapping.py +++ b/src/examples/Display/enviroment_mapping.py @@ -58,7 +58,7 @@ mat_asp.SetShininess(1) mat_asp.SetSpecular(1) -box_ais = display.DisplayShape(box, mat_asp).GetObject() +box_ais = display.DisplayShape(box, mat_asp, update=True).GetObject() attributes = box_ais.Attributes().GetObject() shd_asp = attributes.ShadingAspect().GetObject() shd_asp.SetMaterial(mat_asp, Aspect_TOFM_FRONT_SIDE) diff --git a/src/examples/Display/lightened_shape.py b/src/examples/Display/lightened_shape.py index e6f2fd75e..2a502bcc8 100644 --- a/src/examples/Display/lightened_shape.py +++ b/src/examples/Display/lightened_shape.py @@ -34,6 +34,7 @@ viewer_handle = display.GetViewer() viewer = viewer_handle.GetObject() + # # First remove all lights from current viewer # diff --git a/src/examples/Display/material_face.py b/src/examples/Display/material_face.py index 988d625ec..cb8f74e12 100644 --- a/src/examples/Display/material_face.py +++ b/src/examples/Display/material_face.py @@ -45,7 +45,7 @@ # faces = Topo(s).faces() for face in faces: - display.DisplayShape(face,material_iterator.next()) + display.DisplayShape(face,material_iterator.next(), update=True) display.View_Iso() display.FitAll() diff --git a/src/examples/Display/material_shape.py b/src/examples/Display/material_shape.py index 21e150b01..bbb809d57 100644 --- a/src/examples/Display/material_shape.py +++ b/src/examples/Display/material_shape.py @@ -35,7 +35,7 @@ # ax = gp_Ax2(gp_Pnt(0, 200, 0), gp_Dir(0, 0, 100)) s = BRepPrimAPI_MakeCylinder(ax, 60, 200) -display.DisplayShape(s.Shape()) +display.DisplayShape(s.Shape(), update=True) display.View_Iso() display.FitAll() diff --git a/src/examples/Display/qt_demo.py b/src/examples/Display/qt_demo.py index be68af03a..2213f5e3c 100644 --- a/src/examples/Display/qt_demo.py +++ b/src/examples/Display/qt_demo.py @@ -18,7 +18,6 @@ ##along with pythonOCC. If not, see . from OCC.Display.SimpleGui import * -set_backend('qt') display, start_display, add_menu, add_function_to_menu = init_display() #from OCC.Graphic3d import * @@ -31,7 +30,7 @@ def simple_test(event=None): def simple_cylinder(event=None): s = BRepPrimAPI_MakeCylinder(60, 200) - display.DisplayShape(s.Shape()) + display.DisplayShape(s.Shape(), update=True) # set up menus add_menu('qt tests') diff --git a/src/examples/Display/wx_demo.py b/src/examples/Display/wx_demo.py index f5ee494e9..fcd00a44f 100644 --- a/src/examples/Display/wx_demo.py +++ b/src/examples/Display/wx_demo.py @@ -20,7 +20,6 @@ from OCC.BRepPrimAPI import * from OCC.Display.SimpleGui import * -set_backend('wx') display, start_display, add_menu, add_function_to_menu = init_display() #from OCC.Graphic3d import * diff --git a/src/examples/WebGl/shape.js b/src/examples/WebGl/shape.js index dbfed340c..146c5d5a4 100644 --- a/src/examples/WebGl/shape.js +++ b/src/examples/WebGl/shape.js @@ -1,5006 +1,342 @@ var Shape = function () { var scope = this; THREE.Geometry.call( this ); -v(42.1733,23.185,-9.82287); -v(44.3051,11.3756,-9.04827); -v(40.0842,22.0365,-9.04827); -v(-25.0201,53.1704,-4.81754); -v(-11.0111,57.7222,-4.81754); -v(-24.3928,51.8373,-6.84547); -v(42.1733,23.185,-9.82287); -v(46.6142,11.9685,-9.82287); -v(44.3051,11.3756,-9.04827); -v(-58.2997,-7.36496,4.81754); -v(-59.2152,7.48062,2.4869); -v(-59.2152,-7.48062,2.4869); -v(-58.2997,-7.36496,4.81754); -v(-58.2997,7.36496,4.81754); -v(-59.2152,7.48062,2.4869); -v(3.02187,-48.0312,9.82287); -v(-9.01795,-47.2737,9.82287); -v(3.17895,-50.528,9.98027); -v(3.02187,-48.0312,9.82287); -v(-8.57123,-44.932,9.04827); -v(-9.01795,-47.2737,9.82287); -v(-17.8443,-37.9211,5.87785); -v(-26.7143,-32.2921,5.87785); -v(-18.5749,-39.4738,7.70513); -v(-17.8443,-37.9211,5.87785); -v(-25.9446,-31.3616,3.68125); -v(-26.7143,-32.2921,5.87785); -v(-49.362,19.5438,9.51056); -v(-42.9509,31.2056,9.51056); -v(-51.4708,20.3787,8.44328); -v(-32.4245,-23.5578,-1.25333); -v(-37.844,-14.9835,-3.68125); -v(-37.2644,-14.754,-1.25333); -v(-32.4245,-23.5578,-1.25333); -v(-37.2644,-14.754,-1.25333); -v(-32.4245,-23.5578,1.25333); -v(-29.1572,35.245,9.04827); -v(-19.4761,41.3888,9.04827); -v(-30.6768,37.0819,9.82287); -v(-43.2818,-5.46776,-7.70513); -v(-43.2818,5.46776,-7.70513); -v(-41.5794,-5.25269,-5.87785); -v(-43.2818,-5.46776,-7.70513); -v(-45.3815,5.73302,-9.04827); -v(-43.2818,5.46776,-7.70513); -v(-7.62684,39.9813,3.68125); -v(2.51657,39.9998,1.25333); -v(2.55571,40.6219,3.68125); -v(-7.62684,39.9813,3.68125); -v(2.55571,40.6219,3.68125); -v(-7.85312,41.1675,5.87785); -v(-47.0726,18.6374,-9.98027); -v(-40.9588,29.7583,-9.98027); -v(-44.7466,17.7164,-9.82287); -v(-47.0726,18.6374,-9.98027); -v(-42.9509,31.2056,-9.51056); -v(-40.9588,29.7583,-9.98027); -v(12.5777,38.7101,-3.68125); -v(21.8093,34.366,-3.68125); -v(12.385,38.1173,-1.25333); -v(-36.5178,44.1425,-6.84547); -v(-24.3928,51.8373,-6.84547); -v(-35.2867,42.6543,-8.44328); -v(-36.5178,44.1425,-6.84547); -v(-25.0201,53.1704,-4.81754); -v(-24.3928,51.8373,-6.84547); -v(41.7624,-39.2175,6.84547); -v(30.6973,-48.3713,6.84547); -v(31.4868,-49.6153,4.81754); -v(33.3446,31.3127,-9.04827); -v(40.0842,22.0365,-9.04827); -v(31.8018,29.8639,-7.70513); -v(41.7624,-39.2175,6.84547); -v(31.4868,-49.6153,4.81754); -v(42.8364,-40.2261,4.81754); -v(-55.4945,-21.9718,2.4869); -v(-59.2152,-7.48062,2.4869); -v(-59.5269,-7.51999,-2.44929e-15); -v(-55.4945,-21.9718,2.4869); -v(-59.5269,-7.51999,-2.44929e-15); -v(-55.7866,-22.0875,-2.44929e-15); -v(15.6449,-48.15,9.98027); -v(3.33356,-52.9854,9.51056); -v(16.4058,-50.4918,9.51056); -v(-55.4945,-21.9718,2.4869); -v(-55.7866,-22.0875,-2.44929e-15); -v(-48.541,-35.2671,-2.44929e-15); -v(15.6449,-48.15,9.98027); -v(3.02187,-48.0312,9.82287); -v(3.17895,-50.528,9.98027); -v(15.6449,-48.15,9.98027); -v(3.17895,-50.528,9.98027); -v(3.33356,-52.9854,9.51056); -v(51.4222,13.203,-9.51056); -v(53.0902,-1.30033e-14,-9.51056); -v(49.0373,12.5906,-9.98027); -v(-8.17465,-42.853,7.70513); -v(-17.8443,-37.9211,5.87785); -v(-18.5749,-39.4738,7.70513); -v(-54.9218,6.93823,8.44328); -v(-51.4708,20.3787,8.44328); -v(-53.2666,21.0897,6.84547); -v(-8.17465,-42.853,7.70513); -v(-19.4761,-41.3888,9.04827); -v(-8.57123,-44.932,9.04827); -v(-8.17465,-42.853,7.70513); -v(-18.5749,-39.4738,7.70513); -v(-19.4761,-41.3888,9.04827); -v(-54.9218,6.93823,8.44328); -v(-49.362,19.5438,9.51056); -v(-51.4708,20.3787,8.44328); -v(-25.5472,-30.8813,1.25333); -v(-32.4245,-23.5578,1.25333); -v(-25.9446,-31.3616,3.68125); -v(-54.9218,6.93823,8.44328); -v(-53.2666,21.0897,6.84547); -v(-56.8379,7.1803,6.84547); -v(-25.5472,-30.8813,1.25333); -v(-32.4245,-23.5578,-1.25333); -v(-32.4245,-23.5578,1.25333); -v(-38.9349,28.2879,9.82287); -v(-29.1572,35.245,9.04827); -v(-30.6768,37.0819,9.82287); -v(-38.9349,28.2879,9.82287); -v(-30.6768,37.0819,9.82287); -v(-40.9588,29.7583,9.98027); -v(-38.9668,-15.428,-5.87785); -v(-40.3813,-5.10134,-3.68125); -v(-37.844,-14.9835,-3.68125); -v(-38.9668,-15.428,-5.87785); -v(-43.2818,-5.46776,-7.70513); -v(-41.5794,-5.25269,-5.87785); -v(-17.8443,37.9211,5.87785); -v(-7.62684,39.9813,3.68125); -v(-7.85312,41.1675,5.87785); -v(-38.9668,-15.428,-5.87785); -v(-41.5794,-5.25269,-5.87785); -v(-40.3813,-5.10134,-3.68125); -v(-47.7467,6.03181,-9.82287); -v(-44.7466,17.7164,-9.82287); -v(-42.53,16.8388,-9.04827); -v(-17.8443,37.9211,5.87785); -v(-7.85312,41.1675,5.87785); -v(-18.5749,39.4738,7.70513); -v(-47.7467,6.03181,-9.82287); -v(-47.0726,18.6374,-9.98027); -v(-44.7466,17.7164,-9.82287); -v(-47.7467,6.03181,-9.82287); -v(-42.53,16.8388,-9.04827); -v(-45.3815,5.73302,-9.04827); -v(-44.7858,32.5388,-8.44328); -v(-35.2867,42.6543,-8.44328); -v(-33.8409,40.9067,-9.51056); -v(2.51657,39.9998,-1.25333); -v(12.385,38.1173,-1.25333); -v(2.51657,39.9998,1.25333); -v(-44.7858,32.5388,-8.44328); -v(-33.8409,40.9067,-9.51056); -v(-42.9509,31.2056,-9.51056); -v(2.51657,39.9998,-1.25333); -v(12.5777,38.7101,-3.68125); -v(12.385,38.1173,-1.25333); -v(-44.7858,32.5388,-8.44328); -v(-36.5178,44.1425,-6.84547); -v(-35.2867,42.6543,-8.44328); -v(51.4945,-28.3093,4.81754); -v(42.8364,-40.2261,4.81754); -v(43.5091,-40.8578,2.4869); -v(23.3759,36.8344,-7.70513); -v(33.3446,31.3127,-9.04827); -v(31.8018,29.8639,-7.70513); -v(51.4945,-28.3093,4.81754); -v(43.5091,-40.8578,2.4869); -v(52.3031,-28.7539,2.4869); -v(23.3759,36.8344,-7.70513); -v(30.551,28.6893,-5.87785); -v(22.4564,35.3856,-5.87785); -v(23.3759,36.8344,-7.70513); -v(31.8018,29.8639,-7.70513); -v(30.551,28.6893,-5.87785); -v(28.4471,-44.8255,9.51056); -v(16.4058,-50.4918,9.51056); -v(29.6624,-46.7405,8.44328); -v(44.3656,24.3902,-9.98027); -v(51.4222,13.203,-9.51056); -v(49.0373,12.5906,-9.98027); -v(44.3656,24.3902,-9.98027); -v(49.0373,12.5906,-9.98027); -v(46.6142,11.9685,-9.82287); -v(44.3656,24.3902,-9.98027); -v(46.6142,11.9685,-9.82287); -v(42.1733,23.185,-9.82287); -v(-25.413,54.0054,-2.4869); -v(-25.5468,54.2896,-2.44929e-15); -v(-11.2429,58.9372,-2.44929e-15); -v(-25.413,54.0054,-2.4869); -v(-11.184,58.6286,-2.4869); -v(-11.0111,57.7222,-4.81754); -v(-25.413,54.0054,-2.4869); -v(-11.0111,57.7222,-4.81754); -v(-25.0201,53.1704,-4.81754); -v(-25.413,54.0054,-2.4869); -v(-11.2429,58.9372,-2.44929e-15); -v(-11.184,58.6286,-2.4869); -v(-56.8379,-7.1803,6.84547); -v(-56.8379,7.1803,6.84547); -v(-58.2997,7.36496,4.81754); -v(-56.8379,-7.1803,6.84547); -v(-58.2997,7.36496,4.81754); -v(-58.2997,-7.36496,4.81754); -v(2.87218,-45.6519,9.04827); -v(-8.57123,-44.932,9.04827); -v(3.02187,-48.0312,9.82287); -v(-17.3302,-36.8285,3.68125); -v(-25.5472,-30.8813,1.25333); -v(-25.9446,-31.3616,3.68125); -v(-17.3302,-36.8285,3.68125); -v(-25.9446,-31.3616,3.68125); -v(-17.8443,-37.9211,5.87785); -v(-47.0726,18.6374,9.98027); -v(-38.9349,28.2879,9.82287); -v(-40.9588,29.7583,9.98027); -v(-47.0726,18.6374,9.98027); -v(-40.9588,29.7583,9.98027); -v(-42.9509,31.2056,9.51056); -v(-47.0726,18.6374,9.98027); -v(-42.9509,31.2056,9.51056); -v(-49.362,19.5438,9.51056); -v(-27.8081,33.6142,7.70513); -v(-17.8443,37.9211,5.87785); -v(-18.5749,39.4738,7.70513); -v(-27.8081,33.6142,7.70513); -v(-19.4761,41.3888,9.04827); -v(-29.1572,35.245,9.04827); -v(-32.9288,-23.9242,-3.68125); -v(-37.844,-14.9835,-3.68125); -v(-32.4245,-23.5578,-1.25333); -v(-27.8081,33.6142,7.70513); -v(-18.5749,39.4738,7.70513); -v(-19.4761,41.3888,9.04827); -v(-45.3815,-5.73302,-9.04827); -v(-45.3815,5.73302,-9.04827); -v(-43.2818,-5.46776,-7.70513); -v(-7.51003,39.3689,1.25333); -v(2.51657,39.9998,-1.25333); -v(2.51657,39.9998,1.25333); -v(-7.51003,39.3689,1.25333); -v(2.51657,39.9998,1.25333); -v(-7.62684,39.9813,3.68125); -v(12.9508,39.8586,-5.87785); -v(22.4564,35.3856,-5.87785); -v(21.8093,34.366,-3.68125); -v(-49.362,19.5438,-9.51056); -v(-42.9509,31.2056,-9.51056); -v(-47.0726,18.6374,-9.98027); -v(57.8107,-14.8433,2.4869); -v(58.115,-14.9214,-2.44929e-15); -v(59.6858,-1.46188e-14,2.4869); -v(12.9508,39.8586,-5.87785); -v(23.3759,36.8344,-7.70513); -v(22.4564,35.3856,-5.87785); -v(57.8107,-14.8433,2.4869); -v(59.6858,-1.46188e-14,2.4869); -v(58.7631,-1.43928e-14,4.81754); -v(12.9508,39.8586,-5.87785); -v(21.8093,34.366,-3.68125); -v(12.5777,38.7101,-3.68125); -v(57.8107,-14.8433,2.4869); -v(52.3031,-28.7539,2.4869); -v(58.115,-14.9214,-2.44929e-15); -v(35.0825,32.9446,-9.82287); -v(40.0842,22.0365,-9.04827); -v(33.3446,31.3127,-9.04827); -v(35.0825,32.9446,-9.82287); -v(44.3656,24.3902,-9.98027); -v(42.1733,23.185,-9.82287); -v(-37.457,45.2777,-4.81754); -v(-25.0201,53.1704,-4.81754); -v(-36.5178,44.1425,-6.84547); -v(35.0825,32.9446,-9.82287); -v(42.1733,23.185,-9.82287); -v(40.0842,22.0365,-9.04827); -v(-54.6365,-21.6321,4.81754); -v(-58.2997,-7.36496,4.81754); -v(-59.2152,-7.48062,2.4869); -v(40.3544,-37.8953,8.44328); -v(28.4471,-44.8255,9.51056); -v(29.6624,-46.7405,8.44328); -v(40.3544,-37.8953,8.44328); -v(29.6624,-46.7405,8.44328); -v(30.6973,-48.3713,6.84547); -v(40.3544,-37.8953,8.44328); -v(30.6973,-48.3713,6.84547); -v(41.7624,-39.2175,6.84547); -v(-54.6365,-21.6321,4.81754); -v(-59.2152,-7.48062,2.4869); -v(-55.4945,-21.9718,2.4869); -v(14.8718,-45.7707,9.82287); -v(3.02187,-48.0312,9.82287); -v(15.6449,-48.15,9.98027); -v(53.6191,13.767,-8.44328); -v(53.0902,-1.30033e-14,-9.51056); -v(51.4222,13.203,-9.51056); -v(14.8718,-45.7707,9.82287); -v(2.87218,-45.6519,9.04827); -v(3.02187,-48.0312,9.82287); -v(53.6191,13.767,-8.44328); -v(55.3583,-1.35589e-14,-8.44328); -v(53.0902,-1.30033e-14,-9.51056); -v(-7.85312,-41.1675,5.87785); -v(-17.8443,-37.9211,5.87785); -v(-8.17465,-42.853,7.70513); -v(-7.85312,-41.1675,5.87785); -v(-17.3302,-36.8285,3.68125); -v(-17.8443,-37.9211,5.87785); -v(-52.6715,6.65396,9.51056); -v(-49.362,19.5438,9.51056); -v(-54.9218,6.93823,8.44328); -v(-25.5472,-30.8813,-1.25333); -v(-32.9288,-23.9242,-3.68125); -v(-32.4245,-23.5578,-1.25333); -v(-37.0062,26.8866,9.04827); -v(-29.1572,35.245,9.04827); -v(-38.9349,28.2879,9.82287); -v(-25.5472,-30.8813,-1.25333); -v(-32.4245,-23.5578,-1.25333); -v(-25.5472,-30.8813,1.25333); -v(-17.3302,36.8285,3.68125); -v(-7.62684,39.9813,3.68125); -v(-17.8443,37.9211,5.87785); -v(-40.5622,-16.0597,-7.70513); -v(-43.2818,-5.46776,-7.70513); -v(-38.9668,-15.428,-5.87785); -v(-40.5622,-16.0597,-7.70513); -v(-45.3815,-5.73302,-9.04827); -v(-43.2818,-5.46776,-7.70513); -v(-17.3302,36.8285,3.68125); -v(-7.51003,39.3689,1.25333); -v(-7.62684,39.9813,3.68125); -v(-50.2287,6.34536,-9.98027); -v(-49.362,19.5438,-9.51056); -v(-47.0726,18.6374,-9.98027); -v(2.55571,40.6219,-3.68125); -v(12.5777,38.7101,-3.68125); -v(2.51657,39.9998,-1.25333); -v(-50.2287,6.34536,-9.98027); -v(-47.0726,18.6374,-9.98027); -v(-47.7467,6.03181,-9.82287); -v(-46.3483,33.674,-6.84547); -v(-37.457,45.2777,-4.81754); -v(-36.5178,44.1425,-6.84547); -v(-46.3483,33.674,-6.84547); -v(-36.5178,44.1425,-6.84547); -v(-44.7858,32.5388,-8.44328); -v(24.5099,38.6214,-9.04827); -v(33.3446,31.3127,-9.04827); -v(23.3759,36.8344,-7.70513); -v(50.2033,-27.5995,6.84547); -v(42.8364,-40.2261,4.81754); -v(51.4945,-28.3093,4.81754); -v(-48.2869,-35.0825,2.4869); -v(-55.4945,-21.9718,2.4869); -v(-48.541,-35.2671,-2.44929e-15); -v(50.2033,-27.5995,6.84547); -v(41.7624,-39.2175,6.84547); -v(42.8364,-40.2261,4.81754); -v(27.1278,-42.7466,9.98027); -v(15.6449,-48.15,9.98027); -v(16.4058,-50.4918,9.51056); -v(46.5233,25.5764,-9.51056); -v(51.4222,13.203,-9.51056); -v(44.3656,24.3902,-9.98027); -v(27.1278,-42.7466,9.98027); -v(14.8718,-45.7707,9.82287); -v(15.6449,-48.15,9.98027); -v(27.1278,-42.7466,9.98027); -v(16.4058,-50.4918,9.51056); -v(28.4471,-44.8255,9.51056); -v(-54.9218,-6.93823,8.44328); -v(-56.8379,7.1803,6.84547); -v(-56.8379,-7.1803,6.84547); -v(-54.9218,-6.93823,8.44328); -v(-54.9218,6.93823,8.44328); -v(-56.8379,7.1803,6.84547); -v(2.73928,-43.5397,7.70513); -v(-8.17465,-42.853,7.70513); -v(-8.57123,-44.932,9.04827); -v(2.73928,-43.5397,7.70513); -v(-8.57123,-44.932,9.04827); -v(2.87218,-45.6519,9.04827); -v(2.73928,-43.5397,7.70513); -v(-7.85312,-41.1675,5.87785); -v(-8.17465,-42.853,7.70513); -v(-17.0647,-36.2644,1.25333); -v(-25.5472,-30.8813,1.25333); -v(-17.3302,-36.8285,3.68125); -v(-54.9218,-6.93823,8.44328); -v(-52.6715,6.65396,9.51056); -v(-54.9218,6.93823,8.44328); -v(-17.0647,-36.2644,1.25333); -v(-25.5472,-30.8813,-1.25333); -v(-25.5472,-30.8813,1.25333); -v(-44.7466,17.7164,9.82287); -v(-37.0062,26.8866,9.04827); -v(-38.9349,28.2879,9.82287); -v(-33.9058,-24.634,-5.87785); -v(-38.9668,-15.428,-5.87785); -v(-37.844,-14.9835,-3.68125); -v(-44.7466,17.7164,9.82287); -v(-38.9349,28.2879,9.82287); -v(-47.0726,18.6374,9.98027); -v(-33.9058,-24.634,-5.87785); -v(-40.5622,-16.0597,-7.70513); -v(-38.9668,-15.428,-5.87785); -v(-26.7143,32.2921,5.87785); -v(-17.3302,36.8285,3.68125); -v(-17.8443,37.9211,5.87785); -v(-33.9058,-24.634,-5.87785); -v(-37.844,-14.9835,-3.68125); -v(-32.9288,-23.9242,-3.68125); -v(-47.7467,-6.03181,-9.82287); -v(-45.3815,5.73302,-9.04827); -v(-45.3815,-5.73302,-9.04827); -v(-47.7467,-6.03181,-9.82287); -v(-50.2287,6.34536,-9.98027); -v(-47.7467,6.03181,-9.82287); -v(-26.7143,32.2921,5.87785); -v(-17.8443,37.9211,5.87785); -v(-27.8081,33.6142,7.70513); -v(-47.7467,-6.03181,-9.82287); -v(-47.7467,6.03181,-9.82287); -v(-45.3815,5.73302,-9.04827); -v(-51.4708,20.3787,-8.44328); -v(-42.9509,31.2056,-9.51056); -v(-49.362,19.5438,-9.51056); -v(-7.51003,39.3689,-1.25333); -v(2.51657,39.9998,-1.25333); -v(-7.51003,39.3689,1.25333); -v(-51.4708,20.3787,-8.44328); -v(-46.3483,33.674,-6.84547); -v(-44.7858,32.5388,-8.44328); -v(-7.51003,39.3689,-1.25333); -v(2.55571,40.6219,-3.68125); -v(2.51657,39.9998,-1.25333); -v(-51.4708,20.3787,-8.44328); -v(-44.7858,32.5388,-8.44328); -v(-42.9509,31.2056,-9.51056); -v(56.9169,-14.6138,4.81754); -v(52.3031,-28.7539,2.4869); -v(57.8107,-14.8433,2.4869); -v(13.4811,41.4906,-7.70513); -v(23.3759,36.8344,-7.70513); -v(12.9508,39.8586,-5.87785); -v(56.9169,-14.6138,4.81754); -v(57.8107,-14.8433,2.4869); -v(58.7631,-1.43928e-14,4.81754); -v(56.9169,-14.6138,4.81754); -v(51.4945,-28.3093,4.81754); -v(52.3031,-28.7539,2.4869); -v(13.4811,41.4906,-7.70513); -v(24.5099,38.6214,-9.04827); -v(23.3759,36.8344,-7.70513); -v(-38.0452,45.9887,-2.4869); -v(-38.2454,46.2308,-2.44929e-15); -v(-25.5468,54.2896,-2.44929e-15); -v(-38.0452,45.9887,-2.4869); -v(-25.0201,53.1704,-4.81754); -v(-37.457,45.2777,-4.81754); -v(36.9062,34.6572,-9.98027); -v(46.5233,25.5764,-9.51056); -v(44.3656,24.3902,-9.98027); -v(-38.0452,45.9887,-2.4869); -v(-25.5468,54.2896,-2.44929e-15); -v(-25.413,54.0054,-2.4869); -v(36.9062,34.6572,-9.98027); -v(44.3656,24.3902,-9.98027); -v(35.0825,32.9446,-9.82287); -v(-38.0452,45.9887,-2.4869); -v(-25.413,54.0054,-2.4869); -v(-25.0201,53.1704,-4.81754); -v(-53.2666,-21.0897,6.84547); -v(-56.8379,-7.1803,6.84547); -v(-58.2997,-7.36496,4.81754); -v(38.7011,-36.3427,9.51056); -v(28.4471,-44.8255,9.51056); -v(40.3544,-37.8953,8.44328); -v(14.1351,-43.5034,9.04827); -v(2.87218,-45.6519,9.04827); -v(14.8718,-45.7707,9.82287); -v(-53.2666,-21.0897,6.84547); -v(-58.2997,-7.36496,4.81754); -v(-54.6365,-21.6321,4.81754); -v(55.4898,14.2474,-6.84547); -v(55.3583,-1.35589e-14,-8.44328); -v(53.6191,13.767,-8.44328); -v(-7.62684,-39.9813,3.68125); -v(-17.3302,-36.8285,3.68125); -v(-7.85312,-41.1675,5.87785); -v(-7.62684,-39.9813,3.68125); -v(-17.0647,-36.2644,1.25333); -v(-17.3302,-36.8285,3.68125); -v(55.4898,14.2474,-6.84547); -v(57.2897,-1.40319e-14,-6.84547); -v(55.3583,-1.35589e-14,-8.44328); -v(55.4898,14.2474,-6.84547); -v(58.7631,-1.43928e-14,-4.81754); -v(57.2897,-1.40319e-14,-6.84547); -v(-50.2287,6.34536,9.98027); -v(-47.0726,18.6374,9.98027); -v(-49.362,19.5438,9.51056); -v(-25.9446,-31.3616,-3.68125); -v(-32.9288,-23.9242,-3.68125); -v(-25.5472,-30.8813,-1.25333); -v(-50.2287,6.34536,9.98027); -v(-49.362,19.5438,9.51056); -v(-52.6715,6.65396,9.51056); -v(-50.2287,6.34536,9.98027); -v(-44.7466,17.7164,9.82287); -v(-47.0726,18.6374,9.98027); -v(-35.294,25.6426,7.70513); -v(-27.8081,33.6142,7.70513); -v(-29.1572,35.245,9.04827); -v(-42.53,-16.8388,-9.04827); -v(-45.3815,-5.73302,-9.04827); -v(-40.5622,-16.0597,-7.70513); -v(-35.294,25.6426,7.70513); -v(-29.1572,35.245,9.04827); -v(-37.0062,26.8866,9.04827); -v(-35.294,25.6426,7.70513); -v(-26.7143,32.2921,5.87785); -v(-27.8081,33.6142,7.70513); -v(-17.0647,36.2644,1.25333); -v(-7.51003,39.3689,1.25333); -v(-17.3302,36.8285,3.68125); -v(-52.6715,6.65396,-9.51056); -v(-49.362,19.5438,-9.51056); -v(-50.2287,6.34536,-9.98027); -v(-17.0647,36.2644,1.25333); -v(-7.51003,39.3689,-1.25333); -v(-7.51003,39.3689,1.25333); -v(2.63154,41.8271,-5.87785); -v(12.5777,38.7101,-3.68125); -v(2.55571,40.6219,-3.68125); -v(-47.5403,34.5401,-4.81754); -v(-37.457,45.2777,-4.81754); -v(-46.3483,33.674,-6.84547); -v(48.5108,-26.669,8.44328); -v(40.3544,-37.8953,8.44328); -v(41.7624,-39.2175,6.84547); -v(2.63154,41.8271,-5.87785); -v(12.9508,39.8586,-5.87785); -v(12.5777,38.7101,-3.68125); -v(2.63154,41.8271,-5.87785); -v(13.4811,41.4906,-7.70513); -v(12.9508,39.8586,-5.87785); -v(48.5108,-26.669,8.44328); -v(38.7011,-36.3427,9.51056); -v(40.3544,-37.8953,8.44328); -v(25.7873,40.6343,-9.82287); -v(35.0825,32.9446,-9.82287); -v(33.3446,31.3127,-9.04827); -v(59.6858,-1.46188e-14,2.4869); -v(58.115,-14.9214,-2.44929e-15); -v(60,-1.46958e-14,-2.44929e-15); -v(48.5108,-26.669,8.44328); -v(41.7624,-39.2175,6.84547); -v(50.2033,-27.5995,6.84547); -v(25.7873,40.6343,-9.82287); -v(33.3446,31.3127,-9.04827); -v(24.5099,38.6214,-9.04827); -v(25.7873,-40.6343,9.82287); -v(14.8718,-45.7707,9.82287); -v(27.1278,-42.7466,9.98027); -v(25.7873,-40.6343,9.82287); -v(14.1351,-43.5034,9.04827); -v(14.8718,-45.7707,9.82287); -v(-47.5403,-34.5401,4.81754); -v(-55.4945,-21.9718,2.4869); -v(-48.2869,-35.0825,2.4869); -v(2.63154,-41.8271,5.87785); -v(-7.62684,-39.9813,3.68125); -v(-7.85312,-41.1675,5.87785); -v(-47.5403,-34.5401,4.81754); -v(-54.6365,-21.6321,4.81754); -v(-55.4945,-21.9718,2.4869); -v(2.63154,-41.8271,5.87785); -v(-7.85312,-41.1675,5.87785); -v(2.73928,-43.5397,7.70513); -v(48.5108,26.669,-8.44328); -v(53.6191,13.767,-8.44328); -v(51.4222,13.203,-9.51056); -v(-17.0647,-36.2644,-1.25333); -v(-25.9446,-31.3616,-3.68125); -v(-25.5472,-30.8813,-1.25333); -v(48.5108,26.669,-8.44328); -v(51.4222,13.203,-9.51056); -v(46.5233,25.5764,-9.51056); -v(-17.0647,-36.2644,-1.25333); -v(-25.5472,-30.8813,-1.25333); -v(-17.0647,-36.2644,1.25333); -v(-35.294,-25.6426,-7.70513); -v(-40.5622,-16.0597,-7.70513); -v(-33.9058,-24.634,-5.87785); -v(-52.6715,-6.65396,9.51056); -v(-52.6715,6.65396,9.51056); -v(-54.9218,-6.93823,8.44328); -v(-35.294,-25.6426,-7.70513); -v(-42.53,-16.8388,-9.04827); -v(-40.5622,-16.0597,-7.70513); -v(-42.53,16.8388,9.04827); -v(-37.0062,26.8866,9.04827); -v(-44.7466,17.7164,9.82287); -v(-50.2287,-6.34536,-9.98027); -v(-52.6715,6.65396,-9.51056); -v(-50.2287,6.34536,-9.98027); -v(-50.2287,-6.34536,-9.98027); -v(-50.2287,6.34536,-9.98027); -v(-47.7467,-6.03181,-9.82287); -v(-25.9446,31.3616,3.68125); -v(-17.0647,36.2644,1.25333); -v(-17.3302,36.8285,3.68125); -v(-53.2666,21.0897,-6.84547); -v(-46.3483,33.674,-6.84547); -v(-51.4708,20.3787,-8.44328); -v(-53.2666,21.0897,-6.84547); -v(-47.5403,34.5401,-4.81754); -v(-46.3483,33.674,-6.84547); -v(55.4898,-14.2474,6.84547); -v(56.9169,-14.6138,4.81754); -v(58.7631,-1.43928e-14,4.81754); -v(-25.9446,31.3616,3.68125); -v(-17.3302,36.8285,3.68125); -v(-26.7143,32.2921,5.87785); -v(55.4898,-14.2474,6.84547); -v(58.7631,-1.43928e-14,4.81754); -v(57.2897,-1.40319e-14,6.84547); -v(55.4898,-14.2474,6.84547); -v(51.4945,-28.3093,4.81754); -v(56.9169,-14.6138,4.81754); -v(55.4898,-14.2474,6.84547); -v(50.2033,-27.5995,6.84547); -v(51.4945,-28.3093,4.81754); -v(-7.62684,39.9813,-3.68125); -v(2.55571,40.6219,-3.68125); -v(-7.51003,39.3689,-1.25333); -v(36.9062,-34.6572,9.98027); -v(27.1278,-42.7466,9.98027); -v(28.4471,-44.8255,9.51056); -v(36.9062,-34.6572,9.98027); -v(28.4471,-44.8255,9.51056); -v(38.7011,-36.3427,9.51056); -v(13.4811,-41.4906,7.70513); -v(2.87218,-45.6519,9.04827); -v(14.1351,-43.5034,9.04827); -v(13.4811,-41.4906,7.70513); -v(2.73928,-43.5397,7.70513); -v(2.87218,-45.6519,9.04827); -v(14.1351,43.5034,-9.04827); -v(24.5099,38.6214,-9.04827); -v(13.4811,41.4906,-7.70513); -v(-38.0452,-45.9887,2.4869); -v(-48.2869,-35.0825,2.4869); -v(-48.541,-35.2671,-2.44929e-15); -v(-38.0452,-45.9887,2.4869); -v(-48.541,-35.2671,-2.44929e-15); -v(-38.2454,-46.2308,-2.44929e-15); -v(13.4811,-41.4906,7.70513); -v(2.63154,-41.8271,5.87785); -v(2.73928,-43.5397,7.70513); -v(38.7011,36.3427,-9.51056); -v(46.5233,25.5764,-9.51056); -v(36.9062,34.6572,-9.98027); -v(-7.51003,-39.3689,1.25333); -v(-17.0647,-36.2644,-1.25333); -v(-17.0647,-36.2644,1.25333); -v(-7.51003,-39.3689,1.25333); -v(-17.0647,-36.2644,1.25333); -v(-7.62684,-39.9813,3.68125); -v(-51.4708,-20.3787,8.44328); -v(-52.6715,-6.65396,9.51056); -v(-54.9218,-6.93823,8.44328); -v(-26.7143,-32.2921,-5.87785); -v(-33.9058,-24.634,-5.87785); -v(-32.9288,-23.9242,-3.68125); -v(-26.7143,-32.2921,-5.87785); -v(-32.9288,-23.9242,-3.68125); -v(-25.9446,-31.3616,-3.68125); -v(-51.4708,-20.3787,8.44328); -v(-54.9218,-6.93823,8.44328); -v(-56.8379,-7.1803,6.84547); -v(-26.7143,-32.2921,-5.87785); -v(-35.294,-25.6426,-7.70513); -v(-33.9058,-24.634,-5.87785); -v(-51.4708,-20.3787,8.44328); -v(-56.8379,-7.1803,6.84547); -v(-53.2666,-21.0897,6.84547); -v(-44.7466,-17.7164,-9.82287); -v(-47.7467,-6.03181,-9.82287); -v(-45.3815,-5.73302,-9.04827); -v(-44.7466,-17.7164,-9.82287); -v(-45.3815,-5.73302,-9.04827); -v(-42.53,-16.8388,-9.04827); -v(56.9169,14.6138,-4.81754); -v(58.7631,-1.43928e-14,-4.81754); -v(55.4898,14.2474,-6.84547); -v(-44.7466,-17.7164,-9.82287); -v(-50.2287,-6.34536,-9.98027); -v(-47.7467,-6.03181,-9.82287); -v(-54.9218,6.93823,-8.44328); -v(-53.2666,21.0897,-6.84547); -v(-51.4708,20.3787,-8.44328); -v(-47.7467,6.03181,9.82287); -v(-42.53,16.8388,9.04827); -v(-44.7466,17.7164,9.82287); -v(-54.9218,6.93823,-8.44328); -v(-51.4708,20.3787,-8.44328); -v(-49.362,19.5438,-9.51056); -v(-47.7467,6.03181,9.82287); -v(-44.7466,17.7164,9.82287); -v(-50.2287,6.34536,9.98027); -v(-54.9218,6.93823,-8.44328); -v(-49.362,19.5438,-9.51056); -v(-52.6715,6.65396,-9.51056); -v(-48.2869,35.0825,-2.4869); -v(-48.541,35.2671,-2.44929e-15); -v(-38.2454,46.2308,-2.44929e-15); -v(-48.2869,35.0825,-2.4869); -v(-55.7866,22.0875,-2.44929e-15); -v(-48.541,35.2671,-2.44929e-15); -v(-48.2869,35.0825,-2.4869); -v(-38.0452,45.9887,-2.4869); -v(-37.457,45.2777,-4.81754); -v(-48.2869,35.0825,-2.4869); -v(-38.2454,46.2308,-2.44929e-15); -v(-38.0452,45.9887,-2.4869); -v(-48.2869,35.0825,-2.4869); -v(-37.457,45.2777,-4.81754); -v(-47.5403,34.5401,-4.81754); -v(-33.9058,24.634,5.87785); -v(-25.9446,31.3616,3.68125); -v(-26.7143,32.2921,5.87785); -v(-33.9058,24.634,5.87785); -v(-26.7143,32.2921,5.87785); -v(-35.294,25.6426,7.70513); -v(-17.0647,36.2644,-1.25333); -v(-7.51003,39.3689,-1.25333); -v(-17.0647,36.2644,1.25333); -v(46.5233,-25.5764,9.51056); -v(38.7011,-36.3427,9.51056); -v(48.5108,-26.669,8.44328); -v(24.5099,-38.6214,9.04827); -v(14.1351,-43.5034,9.04827); -v(25.7873,-40.6343,9.82287); -v(-17.0647,36.2644,-1.25333); -v(-7.62684,39.9813,-3.68125); -v(-7.51003,39.3689,-1.25333); -v(2.55571,-40.6219,3.68125); -v(-7.51003,-39.3689,1.25333); -v(-7.62684,-39.9813,3.68125); -v(2.73928,43.5397,-7.70513); -v(13.4811,41.4906,-7.70513); -v(2.63154,41.8271,-5.87785); -v(2.55571,-40.6219,3.68125); -v(-7.62684,-39.9813,3.68125); -v(2.63154,-41.8271,5.87785); -v(2.73928,43.5397,-7.70513); -v(14.1351,43.5034,-9.04827); -v(13.4811,41.4906,-7.70513); -v(27.1278,42.7466,-9.98027); -v(38.7011,36.3427,-9.51056); -v(36.9062,34.6572,-9.98027); -v(-17.3302,-36.8285,-3.68125); -v(-25.9446,-31.3616,-3.68125); -v(-17.0647,-36.2644,-1.25333); -v(27.1278,42.7466,-9.98027); -v(35.0825,32.9446,-9.82287); -v(25.7873,40.6343,-9.82287); -v(27.1278,42.7466,-9.98027); -v(36.9062,34.6572,-9.98027); -v(35.0825,32.9446,-9.82287); -v(-46.3483,-33.674,6.84547); -v(-54.6365,-21.6321,4.81754); -v(-47.5403,-34.5401,4.81754); -v(-37.0062,-26.8866,-9.04827); -v(-42.53,-16.8388,-9.04827); -v(-35.294,-25.6426,-7.70513); -v(-46.3483,-33.674,6.84547); -v(-53.2666,-21.0897,6.84547); -v(-54.6365,-21.6321,4.81754); -v(-52.6715,-6.65396,-9.51056); -v(-52.6715,6.65396,-9.51056); -v(-50.2287,-6.34536,-9.98027); -v(50.2033,27.5995,-6.84547); -v(53.6191,13.767,-8.44328); -v(48.5108,26.669,-8.44328); -v(50.2033,27.5995,-6.84547); -v(56.9169,14.6138,-4.81754); -v(55.4898,14.2474,-6.84547); -v(50.2033,27.5995,-6.84547); -v(55.4898,14.2474,-6.84547); -v(53.6191,13.767,-8.44328); -v(-54.6365,21.6321,-4.81754); -v(-47.5403,34.5401,-4.81754); -v(-53.2666,21.0897,-6.84547); -v(-50.2287,-6.34536,9.98027); -v(-50.2287,6.34536,9.98027); -v(-52.6715,6.65396,9.51056); -v(-50.2287,-6.34536,9.98027); -v(-52.6715,6.65396,9.51056); -v(-52.6715,-6.65396,9.51056); -v(53.6191,-13.767,8.44328); -v(50.2033,-27.5995,6.84547); -v(55.4898,-14.2474,6.84547); -v(53.6191,-13.767,8.44328); -v(57.2897,-1.40319e-14,6.84547); -v(55.3583,-1.35589e-14,8.44328); -v(53.6191,-13.767,8.44328); -v(55.3583,-1.35589e-14,8.44328); -v(53.0902,-1.30033e-14,9.51056); -v(53.6191,-13.767,8.44328); -v(55.4898,-14.2474,6.84547); -v(57.2897,-1.40319e-14,6.84547); -v(53.6191,-13.767,8.44328); -v(48.5108,-26.669,8.44328); -v(50.2033,-27.5995,6.84547); -v(53.6191,-13.767,8.44328); -v(46.5233,-25.5764,9.51056); -v(48.5108,-26.669,8.44328); -v(-50.2287,-6.34536,9.98027); -v(-47.7467,6.03181,9.82287); -v(-50.2287,6.34536,9.98027); -v(-40.5622,16.0597,7.70513); -v(-37.0062,26.8866,9.04827); -v(-42.53,16.8388,9.04827); -v(35.0825,-32.9446,9.82287); -v(27.1278,-42.7466,9.98027); -v(36.9062,-34.6572,9.98027); -v(35.0825,-32.9446,9.82287); -v(25.7873,-40.6343,9.82287); -v(27.1278,-42.7466,9.98027); -v(12.9508,-39.8586,5.87785); -v(2.63154,-41.8271,5.87785); -v(13.4811,-41.4906,7.70513); -v(12.9508,-39.8586,5.87785); -v(2.55571,-40.6219,3.68125); -v(2.63154,-41.8271,5.87785); -v(-40.5622,16.0597,7.70513); -v(-33.9058,24.634,5.87785); -v(-35.294,25.6426,7.70513); -v(-40.5622,16.0597,7.70513); -v(-35.294,25.6426,7.70513); -v(-37.0062,26.8866,9.04827); -v(-25.5472,30.8813,1.25333); -v(-17.0647,36.2644,1.25333); -v(-25.9446,31.3616,3.68125); -v(-7.51003,-39.3689,-1.25333); -v(-17.3302,-36.8285,-3.68125); -v(-17.0647,-36.2644,-1.25333); -v(-25.5472,30.8813,1.25333); -v(-17.0647,36.2644,-1.25333); -v(-17.0647,36.2644,1.25333); -v(-7.85312,41.1675,-5.87785); -v(2.63154,41.8271,-5.87785); -v(2.55571,40.6219,-3.68125); -v(-7.51003,-39.3689,-1.25333); -v(-17.0647,-36.2644,-1.25333); -v(-7.51003,-39.3689,1.25333); -v(-7.85312,41.1675,-5.87785); -v(2.73928,43.5397,-7.70513); -v(2.63154,41.8271,-5.87785); -v(-27.8081,-33.6142,-7.70513); -v(-35.294,-25.6426,-7.70513); -v(-26.7143,-32.2921,-5.87785); -v(-7.85312,41.1675,-5.87785); -v(2.55571,40.6219,-3.68125); -v(-7.62684,39.9813,-3.68125); -v(-27.8081,-33.6142,-7.70513); -v(-37.0062,-26.8866,-9.04827); -v(-35.294,-25.6426,-7.70513); -v(14.8718,45.7707,-9.82287); -v(25.7873,40.6343,-9.82287); -v(24.5099,38.6214,-9.04827); -v(14.8718,45.7707,-9.82287); -v(27.1278,42.7466,-9.98027); -v(25.7873,40.6343,-9.82287); -v(14.8718,45.7707,-9.82287); -v(24.5099,38.6214,-9.04827); -v(14.1351,43.5034,-9.04827); -v(-37.457,-45.2777,4.81754); -v(-48.2869,-35.0825,2.4869); -v(-38.0452,-45.9887,2.4869); -v(-47.0726,-18.6374,-9.98027); -v(-50.2287,-6.34536,-9.98027); -v(-44.7466,-17.7164,-9.82287); -v(-47.0726,-18.6374,-9.98027); -v(-52.6715,-6.65396,-9.51056); -v(-50.2287,-6.34536,-9.98027); -v(-56.8379,7.1803,-6.84547); -v(-53.2666,21.0897,-6.84547); -v(-54.9218,6.93823,-8.44328); -v(-56.8379,7.1803,-6.84547); -v(-54.6365,21.6321,-4.81754); -v(-53.2666,21.0897,-6.84547); -v(-37.457,-45.2777,4.81754); -v(-47.5403,-34.5401,4.81754); -v(-48.2869,-35.0825,2.4869); -v(44.3656,-24.3902,9.98027); -v(36.9062,-34.6572,9.98027); -v(38.7011,-36.3427,9.51056); -v(44.3656,-24.3902,9.98027); -v(35.0825,-32.9446,9.82287); -v(36.9062,-34.6572,9.98027); -v(40.3544,37.8953,-8.44328); -v(48.5108,26.669,-8.44328); -v(46.5233,25.5764,-9.51056); -v(40.3544,37.8953,-8.44328); -v(46.5233,25.5764,-9.51056); -v(38.7011,36.3427,-9.51056); -v(44.3656,-24.3902,9.98027); -v(38.7011,-36.3427,9.51056); -v(46.5233,-25.5764,9.51056); -v(40.3544,37.8953,-8.44328); -v(50.2033,27.5995,-6.84547); -v(48.5108,26.669,-8.44328); -v(23.3759,-36.8344,7.70513); -v(13.4811,-41.4906,7.70513); -v(14.1351,-43.5034,9.04827); -v(23.3759,-36.8344,7.70513); -v(12.9508,-39.8586,5.87785); -v(13.4811,-41.4906,7.70513); -v(23.3759,-36.8344,7.70513); -v(14.1351,-43.5034,9.04827); -v(24.5099,-38.6214,9.04827); -v(-49.362,-19.5438,9.51056); -v(-52.6715,-6.65396,9.51056); -v(-51.4708,-20.3787,8.44328); -v(57.8107,14.8433,-2.4869); -v(58.115,14.9214,-2.44929e-15); -v(60,-1.46958e-14,-2.44929e-15); -v(57.8107,14.8433,-2.4869); -v(52.5784,28.9052,-2.44929e-15); -v(58.115,14.9214,-2.44929e-15); -v(57.8107,14.8433,-2.4869); -v(58.7631,-1.43928e-14,-4.81754); -v(56.9169,14.6138,-4.81754); -v(2.51657,-39.9998,1.25333); -v(-7.51003,-39.3689,-1.25333); -v(-7.51003,-39.3689,1.25333); -v(2.51657,-39.9998,1.25333); -v(-7.51003,-39.3689,1.25333); -v(2.55571,-40.6219,3.68125); -v(57.8107,14.8433,-2.4869); -v(59.6858,-1.46188e-14,-2.4869); -v(58.7631,-1.43928e-14,-4.81754); -v(57.8107,14.8433,2.4869); -v(60,-1.46958e-14,-2.44929e-15); -v(58.115,14.9214,-2.44929e-15); -v(57.8107,14.8433,-2.4869); -v(60,-1.46958e-14,-2.44929e-15); -v(59.6858,-1.46188e-14,-2.4869); -v(-17.8443,-37.9211,-5.87785); -v(-26.7143,-32.2921,-5.87785); -v(-25.9446,-31.3616,-3.68125); -v(57.8107,14.8433,2.4869); -v(58.115,14.9214,-2.44929e-15); -v(52.5784,28.9052,-2.44929e-15); -v(-17.8443,-37.9211,-5.87785); -v(-25.9446,-31.3616,-3.68125); -v(-17.3302,-36.8285,-3.68125); -v(57.8107,14.8433,2.4869); -v(59.6858,-1.46188e-14,2.4869); -v(60,-1.46958e-14,-2.44929e-15); -v(-45.3815,5.73302,9.04827); -v(-42.53,16.8388,9.04827); -v(-47.7467,6.03181,9.82287); -v(-17.8443,-37.9211,-5.87785); -v(-27.8081,-33.6142,-7.70513); -v(-26.7143,-32.2921,-5.87785); -v(56.9169,14.6138,4.81754); -v(59.6858,-1.46188e-14,2.4869); -v(57.8107,14.8433,2.4869); -v(56.9169,14.6138,4.81754); -v(58.7631,-1.43928e-14,4.81754); -v(59.6858,-1.46188e-14,2.4869); -v(-38.9349,-28.2879,-9.82287); -v(-44.7466,-17.7164,-9.82287); -v(-42.53,-16.8388,-9.04827); -v(-32.9288,23.9242,3.68125); -v(-25.5472,30.8813,1.25333); -v(-25.9446,31.3616,3.68125); -v(-38.9349,-28.2879,-9.82287); -v(-42.53,-16.8388,-9.04827); -v(-37.0062,-26.8866,-9.04827); -v(-32.9288,23.9242,3.68125); -v(-25.9446,31.3616,3.68125); -v(-33.9058,24.634,5.87785); -v(52.3031,28.7539,2.4869); -v(57.8107,14.8433,2.4869); -v(52.5784,28.9052,-2.44929e-15); -v(-38.9349,-28.2879,-9.82287); -v(-47.0726,-18.6374,-9.98027); -v(-44.7466,-17.7164,-9.82287); -v(-54.9218,-6.93823,-8.44328); -v(-54.9218,6.93823,-8.44328); -v(-52.6715,6.65396,-9.51056); -v(-54.9218,-6.93823,-8.44328); -v(-56.8379,7.1803,-6.84547); -v(-54.9218,6.93823,-8.44328); -v(-54.9218,-6.93823,-8.44328); -v(-52.6715,6.65396,-9.51056); -v(-52.6715,-6.65396,-9.51056); -v(55.4898,14.2474,6.84547); -v(58.7631,-1.43928e-14,4.81754); -v(56.9169,14.6138,4.81754); -v(-17.3302,36.8285,-3.68125); -v(-7.62684,39.9813,-3.68125); -v(-17.0647,36.2644,-1.25333); -v(55.4898,14.2474,6.84547); -v(57.2897,-1.40319e-14,6.84547); -v(58.7631,-1.43928e-14,4.81754); -v(-55.4945,21.9718,-2.4869); -v(-55.7866,22.0875,-2.44929e-15); -v(-48.2869,35.0825,-2.4869); -v(-55.4945,21.9718,-2.4869); -v(-59.5269,7.51999,-2.44929e-15); -v(-55.7866,22.0875,-2.44929e-15); -v(-55.4945,21.9718,-2.4869); -v(-48.2869,35.0825,-2.4869); -v(-47.5403,34.5401,-4.81754); -v(-55.4945,21.9718,-2.4869); -v(-47.5403,34.5401,-4.81754); -v(-54.6365,21.6321,-4.81754); -v(2.87218,45.6519,-9.04827); -v(14.1351,43.5034,-9.04827); -v(2.73928,43.5397,-7.70513); -v(51.4222,-13.203,9.51056); -v(46.5233,-25.5764,9.51056); -v(53.6191,-13.767,8.44328); -v(51.4222,-13.203,9.51056); -v(53.6191,-13.767,8.44328); -v(53.0902,-1.30033e-14,9.51056); -v(33.3446,-31.3127,9.04827); -v(24.5099,-38.6214,9.04827); -v(25.7873,-40.6343,9.82287); -v(51.4945,28.3093,4.81754); -v(56.9169,14.6138,4.81754); -v(57.8107,14.8433,2.4869); -v(51.4945,28.3093,4.81754); -v(57.8107,14.8433,2.4869); -v(52.3031,28.7539,2.4869); -v(28.4471,44.8255,-9.51056); -v(38.7011,36.3427,-9.51056); -v(27.1278,42.7466,-9.98027); -v(33.3446,-31.3127,9.04827); -v(25.7873,-40.6343,9.82287); -v(35.0825,-32.9446,9.82287); -v(43.5091,40.8578,2.4869); -v(52.5784,28.9052,-2.44929e-15); -v(43.7381,41.0728,-2.44929e-15); -v(43.5091,40.8578,2.4869); -v(43.7381,41.0728,-2.44929e-15); -v(32.1496,50.6597,-2.44929e-15); -v(-25.413,-54.0054,2.4869); -v(-38.0452,-45.9887,2.4869); -v(-38.2454,-46.2308,-2.44929e-15); -v(-25.413,-54.0054,2.4869); -v(-38.2454,-46.2308,-2.44929e-15); -v(-25.5468,-54.2896,-2.44929e-15); -v(43.5091,40.8578,2.4869); -v(52.3031,28.7539,2.4869); -v(52.5784,28.9052,-2.44929e-15); -v(12.5777,-38.7101,3.68125); -v(2.51657,-39.9998,1.25333); -v(2.55571,-40.6219,3.68125); -v(53.6191,13.767,8.44328); -v(57.2897,-1.40319e-14,6.84547); -v(55.4898,14.2474,6.84547); -v(12.5777,-38.7101,3.68125); -v(2.55571,-40.6219,3.68125); -v(12.9508,-39.8586,5.87785); -v(53.6191,13.767,8.44328); -v(55.3583,-1.35589e-14,8.44328); -v(57.2897,-1.40319e-14,6.84547); -v(53.6191,13.767,8.44328); -v(53.0902,-1.30033e-14,9.51056); -v(55.3583,-1.35589e-14,8.44328); -v(-7.62684,-39.9813,-3.68125); -v(-17.3302,-36.8285,-3.68125); -v(-7.51003,-39.3689,-1.25333); -v(-44.7858,-32.5388,8.44328); -v(-51.4708,-20.3787,8.44328); -v(-53.2666,-21.0897,6.84547); -v(50.2033,27.5995,6.84547); -v(55.4898,14.2474,6.84547); -v(56.9169,14.6138,4.81754); -v(-44.7858,-32.5388,8.44328); -v(-53.2666,-21.0897,6.84547); -v(-46.3483,-33.674,6.84547); -v(-44.7858,-32.5388,8.44328); -v(-49.362,-19.5438,9.51056); -v(-51.4708,-20.3787,8.44328); -v(50.2033,27.5995,6.84547); -v(56.9169,14.6138,4.81754); -v(51.4945,28.3093,4.81754); -v(51.4945,28.3093,-4.81754); -v(56.9169,14.6138,-4.81754); -v(50.2033,27.5995,-6.84547); -v(-29.1572,-35.245,-9.04827); -v(-37.0062,-26.8866,-9.04827); -v(-27.8081,-33.6142,-7.70513); -v(-47.7467,-6.03181,9.82287); -v(-47.7467,6.03181,9.82287); -v(-50.2287,-6.34536,9.98027); -v(42.8364,40.2261,4.81754); -v(52.3031,28.7539,2.4869); -v(43.5091,40.8578,2.4869); -v(-49.362,-19.5438,-9.51056); -v(-52.6715,-6.65396,-9.51056); -v(-47.0726,-18.6374,-9.98027); -v(42.8364,40.2261,4.81754); -v(51.4945,28.3093,4.81754); -v(52.3031,28.7539,2.4869); -v(-47.7467,-6.03181,9.82287); -v(-45.3815,5.73302,9.04827); -v(-47.7467,6.03181,9.82287); -v(-58.2997,7.36496,-4.81754); -v(-54.6365,21.6321,-4.81754); -v(-56.8379,7.1803,-6.84547); -v(-38.9668,15.428,5.87785); -v(-32.9288,23.9242,3.68125); -v(-33.9058,24.634,5.87785); -v(51.4222,13.203,9.51056); -v(53.0902,-1.30033e-14,9.51056); -v(53.6191,13.767,8.44328); -v(42.1733,-23.185,9.82287); -v(35.0825,-32.9446,9.82287); -v(44.3656,-24.3902,9.98027); -v(-38.9668,15.428,5.87785); -v(-33.9058,24.634,5.87785); -v(-40.5622,16.0597,7.70513); -v(42.1733,-23.185,9.82287); -v(33.3446,-31.3127,9.04827); -v(35.0825,-32.9446,9.82287); -v(31.9813,50.3944,2.4869); -v(43.5091,40.8578,2.4869); -v(32.1496,50.6597,-2.44929e-15); -v(-25.5472,30.8813,-1.25333); -v(-17.3302,36.8285,-3.68125); -v(-17.0647,36.2644,-1.25333); -v(22.4564,-35.3856,5.87785); -v(12.9508,-39.8586,5.87785); -v(23.3759,-36.8344,7.70513); -v(22.4564,-35.3856,5.87785); -v(12.5777,-38.7101,3.68125); -v(12.9508,-39.8586,5.87785); -v(48.5108,26.669,8.44328); -v(53.6191,13.767,8.44328); -v(55.4898,14.2474,6.84547); -v(-25.5472,30.8813,-1.25333); -v(-17.0647,36.2644,-1.25333); -v(-25.5472,30.8813,1.25333); -v(48.5108,26.669,8.44328); -v(51.4222,13.203,9.51056); -v(53.6191,13.767,8.44328); -v(-8.17465,42.853,-7.70513); -v(2.73928,43.5397,-7.70513); -v(-7.85312,41.1675,-5.87785); -v(2.51657,-39.9998,-1.25333); -v(-7.62684,-39.9813,-3.68125); -v(-7.51003,-39.3689,-1.25333); -v(-8.17465,42.853,-7.70513); -v(2.87218,45.6519,-9.04827); -v(2.73928,43.5397,-7.70513); -v(2.51657,-39.9998,-1.25333); -v(-7.51003,-39.3689,-1.25333); -v(2.51657,-39.9998,1.25333); -v(48.5108,26.669,8.44328); -v(55.4898,14.2474,6.84547); -v(50.2033,27.5995,6.84547); -v(-18.5749,-39.4738,-7.70513); -v(-29.1572,-35.245,-9.04827); -v(-27.8081,-33.6142,-7.70513); -v(41.7624,39.2175,6.84547); -v(51.4945,28.3093,4.81754); -v(42.8364,40.2261,4.81754); -v(15.6449,48.15,-9.98027); -v(28.4471,44.8255,-9.51056); -v(27.1278,42.7466,-9.98027); -v(15.6449,48.15,-9.98027); -v(27.1278,42.7466,-9.98027); -v(14.8718,45.7707,-9.82287); -v(-18.5749,-39.4738,-7.70513); -v(-27.8081,-33.6142,-7.70513); -v(-17.8443,-37.9211,-5.87785); -v(-40.9588,-29.7583,-9.98027); -v(-49.362,-19.5438,-9.51056); -v(-47.0726,-18.6374,-9.98027); -v(41.7624,39.2175,6.84547); -v(50.2033,27.5995,6.84547); -v(51.4945,28.3093,4.81754); -v(-40.9588,-29.7583,-9.98027); -v(-47.0726,-18.6374,-9.98027); -v(-38.9349,-28.2879,-9.82287); -v(-36.5178,-44.1425,6.84547); -v(-46.3483,-33.674,6.84547); -v(-47.5403,-34.5401,4.81754); -v(49.0373,12.5906,9.98027); -v(53.0902,-1.30033e-14,9.51056); -v(51.4222,13.203,9.51056); -v(-56.8379,-7.1803,-6.84547); -v(-58.2997,7.36496,-4.81754); -v(-56.8379,7.1803,-6.84547); -v(49.0373,12.5906,9.98027); -v(50.6279,-1.24003e-14,9.98027); -v(53.0902,-1.30033e-14,9.51056); -v(-36.5178,-44.1425,6.84547); -v(-47.5403,-34.5401,4.81754); -v(-37.457,-45.2777,4.81754); -v(-56.8379,-7.1803,-6.84547); -v(-56.8379,7.1803,-6.84547); -v(-54.9218,-6.93823,-8.44328); -v(41.7624,39.2175,-6.84547); -v(51.4945,28.3093,-4.81754); -v(50.2033,27.5995,-6.84547); -v(49.0373,-12.5906,9.98027); -v(53.0902,-1.30033e-14,9.51056); -v(50.6279,-1.24003e-14,9.98027); -v(41.7624,39.2175,-6.84547); -v(50.2033,27.5995,-6.84547); -v(40.3544,37.8953,-8.44328); -v(31.4868,49.6153,4.81754); -v(42.8364,40.2261,4.81754); -v(43.5091,40.8578,2.4869); -v(49.0373,-12.5906,9.98027); -v(51.4222,-13.203,9.51056); -v(53.0902,-1.30033e-14,9.51056); -v(49.0373,-12.5906,9.98027); -v(44.3656,-24.3902,9.98027); -v(46.5233,-25.5764,9.51056); -v(49.0373,-12.5906,9.98027); -v(46.5233,-25.5764,9.51056); -v(51.4222,-13.203,9.51056); -v(31.4868,49.6153,4.81754); -v(43.5091,40.8578,2.4869); -v(31.9813,50.3944,2.4869); -v(-47.0726,-18.6374,9.98027); -v(-50.2287,-6.34536,9.98027); -v(-52.6715,-6.65396,9.51056); -v(31.8018,-29.8639,7.70513); -v(24.5099,-38.6214,9.04827); -v(33.3446,-31.3127,9.04827); -v(46.5233,25.5764,9.51056); -v(51.4222,13.203,9.51056); -v(48.5108,26.669,8.44328); -v(-47.0726,-18.6374,9.98027); -v(-52.6715,-6.65396,9.51056); -v(-49.362,-19.5438,9.51056); -v(31.8018,-29.8639,7.70513); -v(23.3759,-36.8344,7.70513); -v(24.5099,-38.6214,9.04827); -v(-47.0726,-18.6374,9.98027); -v(-47.7467,-6.03181,9.82287); -v(-50.2287,-6.34536,9.98027); -v(12.385,-38.1173,1.25333); -v(2.51657,-39.9998,-1.25333); -v(2.51657,-39.9998,1.25333); -v(-43.2818,5.46776,7.70513); -v(-38.9668,15.428,5.87785); -v(-40.5622,16.0597,7.70513); -v(-43.2818,5.46776,7.70513); -v(-40.5622,16.0597,7.70513); -v(-42.53,16.8388,9.04827); -v(12.385,-38.1173,1.25333); -v(2.51657,-39.9998,1.25333); -v(12.5777,-38.7101,3.68125); -v(18.4439,56.7646,2.4869); -v(32.1496,50.6597,-2.44929e-15); -v(18.541,57.0634,-2.44929e-15); -v(-43.2818,5.46776,7.70513); -v(-42.53,16.8388,9.04827); -v(-45.3815,5.73302,9.04827); -v(-7.85312,-41.1675,-5.87785); -v(-18.5749,-39.4738,-7.70513); -v(-17.8443,-37.9211,-5.87785); -v(18.4439,56.7646,2.4869); -v(18.541,57.0634,-2.44929e-15); -v(3.76743,59.8816,-2.44929e-15); -v(-7.85312,-41.1675,-5.87785); -v(-17.8443,-37.9211,-5.87785); -v(-17.3302,-36.8285,-3.68125); -v(18.4439,56.7646,2.4869); -v(31.9813,50.3944,2.4869); -v(32.1496,50.6597,-2.44929e-15); -v(-7.85312,-41.1675,-5.87785); -v(-17.3302,-36.8285,-3.68125); -v(-7.62684,-39.9813,-3.68125); -v(-32.4245,23.5578,1.25333); -v(-25.5472,30.8813,-1.25333); -v(-25.5472,30.8813,1.25333); -v(-32.4245,23.5578,1.25333); -v(-25.5472,30.8813,1.25333); -v(-32.9288,23.9242,3.68125); -v(-30.6768,-37.0819,-9.82287); -v(-37.0062,-26.8866,-9.04827); -v(-29.1572,-35.245,-9.04827); -v(-17.8443,37.9211,-5.87785); -v(-7.62684,39.9813,-3.68125); -v(-17.3302,36.8285,-3.68125); -v(40.3544,37.8953,8.44328); -v(48.5108,26.669,8.44328); -v(50.2033,27.5995,6.84547); -v(-17.8443,37.9211,-5.87785); -v(-8.17465,42.853,-7.70513); -v(-7.85312,41.1675,-5.87785); -v(-30.6768,-37.0819,-9.82287); -v(-40.9588,-29.7583,-9.98027); -v(-38.9349,-28.2879,-9.82287); -v(40.3544,37.8953,8.44328); -v(46.5233,25.5764,9.51056); -v(48.5108,26.669,8.44328); -v(40.3544,37.8953,8.44328); -v(50.2033,27.5995,6.84547); -v(41.7624,39.2175,6.84547); -v(-30.6768,-37.0819,-9.82287); -v(-38.9349,-28.2879,-9.82287); -v(-37.0062,-26.8866,-9.04827); -v(-17.8443,37.9211,-5.87785); -v(-7.85312,41.1675,-5.87785); -v(-7.62684,39.9813,-3.68125); -v(3.02187,48.0312,-9.82287); -v(14.1351,43.5034,-9.04827); -v(2.87218,45.6519,-9.04827); -v(46.6142,11.9685,9.82287); -v(48.1262,-1.17875e-14,9.82287); -v(50.6279,-1.24003e-14,9.98027); -v(-51.4708,-20.3787,-8.44328); -v(-52.6715,-6.65396,-9.51056); -v(-49.362,-19.5438,-9.51056); -v(-51.4708,-20.3787,-8.44328); -v(-56.8379,-7.1803,-6.84547); -v(-54.9218,-6.93823,-8.44328); -v(-51.4708,-20.3787,-8.44328); -v(-54.9218,-6.93823,-8.44328); -v(-52.6715,-6.65396,-9.51056); -v(-59.2152,7.48062,-2.4869); -v(-54.6365,21.6321,-4.81754); -v(-58.2997,7.36496,-4.81754); -v(3.02187,48.0312,-9.82287); -v(14.8718,45.7707,-9.82287); -v(14.1351,43.5034,-9.04827); -v(3.02187,48.0312,-9.82287); -v(15.6449,48.15,-9.98027); -v(14.8718,45.7707,-9.82287); -v(-59.2152,7.48062,-2.4869); -v(-59.5269,7.51999,-2.44929e-15); -v(-55.4945,21.9718,-2.4869); -v(46.6142,11.9685,9.82287); -v(50.6279,-1.24003e-14,9.98027); -v(49.0373,12.5906,9.98027); -v(-59.2152,7.48062,-2.4869); -v(-55.4945,21.9718,-2.4869); -v(-54.6365,21.6321,-4.81754); -v(40.0842,-22.0365,9.04827); -v(33.3446,-31.3127,9.04827); -v(42.1733,-23.185,9.82287); -v(-25.0201,-53.1704,4.81754); -v(-37.457,-45.2777,4.81754); -v(-38.0452,-45.9887,2.4869); -v(30.6973,48.3713,6.84547); -v(41.7624,39.2175,6.84547); -v(42.8364,40.2261,4.81754); -v(21.8093,-34.366,3.68125); -v(12.5777,-38.7101,3.68125); -v(22.4564,-35.3856,5.87785); -v(30.6973,48.3713,6.84547); -v(42.8364,40.2261,4.81754); -v(31.4868,49.6153,4.81754); -v(-25.0201,-53.1704,4.81754); -v(-38.0452,-45.9887,2.4869); -v(-25.413,-54.0054,2.4869); -v(21.8093,-34.366,3.68125); -v(12.385,-38.1173,1.25333); -v(12.5777,-38.7101,3.68125); -v(29.6624,46.7405,-8.44328); -v(38.7011,36.3427,-9.51056); -v(28.4471,44.8255,-9.51056); -v(44.3656,24.3902,9.98027); -v(51.4222,13.203,9.51056); -v(46.5233,25.5764,9.51056); -v(29.6624,46.7405,-8.44328); -v(40.3544,37.8953,-8.44328); -v(38.7011,36.3427,-9.51056); -v(44.3656,24.3902,9.98027); -v(49.0373,12.5906,9.98027); -v(51.4222,13.203,9.51056); -v(2.55571,-40.6219,-3.68125); -v(-7.62684,-39.9813,-3.68125); -v(2.51657,-39.9998,-1.25333); -v(-19.4761,-41.3888,-9.04827); -v(-29.1572,-35.245,-9.04827); -v(-18.5749,-39.4738,-7.70513); -v(-42.9509,-31.2056,9.51056); -v(-49.362,-19.5438,9.51056); -v(-44.7858,-32.5388,8.44328); -v(52.3031,28.7539,-2.4869); -v(56.9169,14.6138,-4.81754); -v(51.4945,28.3093,-4.81754); -v(52.3031,28.7539,-2.4869); -v(52.5784,28.9052,-2.44929e-15); -v(57.8107,14.8433,-2.4869); -v(52.3031,28.7539,-2.4869); -v(57.8107,14.8433,-2.4869); -v(56.9169,14.6138,-4.81754); -v(-42.9509,-31.2056,-9.51056); -v(-49.362,-19.5438,-9.51056); -v(-40.9588,-29.7583,-9.98027); -v(18.1588,55.887,4.81754); -v(31.4868,49.6153,4.81754); -v(31.9813,50.3944,2.4869); -v(18.1588,55.887,4.81754); -v(31.9813,50.3944,2.4869); -v(18.4439,56.7646,2.4869); -v(-45.3815,-5.73302,9.04827); -v(-45.3815,5.73302,9.04827); -v(-47.7467,-6.03181,9.82287); -v(38.7011,36.3427,9.51056); -v(46.5233,25.5764,9.51056); -v(40.3544,37.8953,8.44328); -v(-58.2997,-7.36496,-4.81754); -v(-58.2997,7.36496,-4.81754); -v(-56.8379,-7.1803,-6.84547); -v(46.6142,-11.9685,9.82287); -v(44.3656,-24.3902,9.98027); -v(49.0373,-12.5906,9.98027); -v(46.6142,-11.9685,9.82287); -v(50.6279,-1.24003e-14,9.98027); -v(48.1262,-1.17875e-14,9.82287); -v(44.3051,11.3756,9.04827); -v(48.1262,-1.17875e-14,9.82287); -v(46.6142,11.9685,9.82287); -v(-37.844,14.9835,3.68125); -v(-32.4245,23.5578,1.25333); -v(-32.9288,23.9242,3.68125); -v(-37.844,14.9835,3.68125); -v(-32.9288,23.9242,3.68125); -v(-38.9668,15.428,5.87785); -v(46.6142,-11.9685,9.82287); -v(49.0373,-12.5906,9.98027); -v(50.6279,-1.24003e-14,9.98027); -v(44.3051,11.3756,9.04827); -v(45.7422,-1.12036e-14,9.04827); -v(48.1262,-1.17875e-14,9.82287); -v(46.6142,-11.9685,9.82287); -v(42.1733,-23.185,9.82287); -v(44.3656,-24.3902,9.98027); -v(30.551,-28.6893,5.87785); -v(23.3759,-36.8344,7.70513); -v(31.8018,-29.8639,7.70513); -v(3.7477,59.5681,2.4869); -v(18.4439,56.7646,2.4869); -v(3.76743,59.8816,-2.44929e-15); -v(-25.9446,31.3616,-3.68125); -v(-17.3302,36.8285,-3.68125); -v(-25.5472,30.8813,-1.25333); -v(30.551,-28.6893,5.87785); -v(22.4564,-35.3856,5.87785); -v(23.3759,-36.8344,7.70513); -v(-8.57123,44.932,-9.04827); -v(2.87218,45.6519,-9.04827); -v(-8.17465,42.853,-7.70513); -v(29.6624,46.7405,8.44328); -v(40.3544,37.8953,8.44328); -v(41.7624,39.2175,6.84547); -v(12.385,-38.1173,-1.25333); -v(2.55571,-40.6219,-3.68125); -v(2.51657,-39.9998,-1.25333); -v(29.6624,46.7405,8.44328); -v(38.7011,36.3427,9.51056); -v(40.3544,37.8953,8.44328); -v(12.385,-38.1173,-1.25333); -v(2.51657,-39.9998,-1.25333); -v(12.385,-38.1173,1.25333); -v(16.4058,50.4918,-9.51056); -v(28.4471,44.8255,-9.51056); -v(15.6449,48.15,-9.98027); -v(-8.17465,-42.853,-7.70513); -v(-18.5749,-39.4738,-7.70513); -v(-7.85312,-41.1675,-5.87785); -v(29.6624,46.7405,8.44328); -v(41.7624,39.2175,6.84547); -v(30.6973,48.3713,6.84547); -v(-8.17465,-42.853,-7.70513); -v(-19.4761,-41.3888,-9.04827); -v(-18.5749,-39.4738,-7.70513); -v(-11.184,-58.6286,2.4869); -v(-25.413,-54.0054,2.4869); -v(-25.5468,-54.2896,-2.44929e-15); -v(42.1733,23.185,9.82287); -v(49.0373,12.5906,9.98027); -v(44.3656,24.3902,9.98027); -v(42.1733,23.185,9.82287); -v(46.6142,11.9685,9.82287); -v(49.0373,12.5906,9.98027); -v(-11.184,-58.6286,2.4869); -v(-25.5468,-54.2896,-2.44929e-15); -v(-11.2429,-58.9372,-2.44929e-15); -v(-32.2714,-39.0095,-9.98027); -v(-40.9588,-29.7583,-9.98027); -v(-30.6768,-37.0819,-9.82287); -v(-35.2867,-42.6543,8.44328); -v(-44.7858,-32.5388,8.44328); -v(-46.3483,-33.674,6.84547); -v(-32.2714,-39.0095,-9.98027); -v(-42.9509,-31.2056,-9.51056); -v(-40.9588,-29.7583,-9.98027); -v(-53.2666,-21.0897,-6.84547); -v(-58.2997,-7.36496,-4.81754); -v(-56.8379,-7.1803,-6.84547); -v(17.7035,54.4857,6.84547); -v(30.6973,48.3713,6.84547); -v(31.4868,49.6153,4.81754); -v(-53.2666,-21.0897,-6.84547); -v(-56.8379,-7.1803,-6.84547); -v(-51.4708,-20.3787,-8.44328); -v(-35.2867,-42.6543,8.44328); -v(-46.3483,-33.674,6.84547); -v(-36.5178,-44.1425,6.84547); -v(-35.2867,-42.6543,8.44328); -v(-42.9509,-31.2056,9.51056); -v(-44.7858,-32.5388,8.44328); -v(17.7035,54.4857,6.84547); -v(31.4868,49.6153,4.81754); -v(18.1588,55.887,4.81754); -v(42.8364,40.2261,-4.81754); -v(51.4945,28.3093,-4.81754); -v(41.7624,39.2175,-6.84547); -v(38.2295,-21.0169,7.70513); -v(33.3446,-31.3127,9.04827); -v(40.0842,-22.0365,9.04827); -v(38.2295,-21.0169,7.70513); -v(31.8018,-29.8639,7.70513); -v(33.3446,-31.3127,9.04827); -v(38.2295,-21.0169,7.70513); -v(30.551,-28.6893,5.87785); -v(31.8018,-29.8639,7.70513); -v(21.4753,-33.8397,1.25333); -v(12.385,-38.1173,1.25333); -v(21.8093,-34.366,3.68125); -v(-44.7466,-17.7164,9.82287); -v(-45.3815,-5.73302,9.04827); -v(-47.7467,-6.03181,9.82287); -v(-44.7466,-17.7164,9.82287); -v(-47.7467,-6.03181,9.82287); -v(-47.0726,-18.6374,9.98027); -v(36.9062,34.6572,9.98027); -v(44.3656,24.3902,9.98027); -v(46.5233,25.5764,9.51056); -v(36.9062,34.6572,9.98027); -v(46.5233,25.5764,9.51056); -v(38.7011,36.3427,9.51056); -v(36.9062,34.6572,9.98027); -v(42.1733,23.185,9.82287); -v(44.3656,24.3902,9.98027); -v(21.4753,-33.8397,1.25333); -v(12.385,-38.1173,-1.25333); -v(12.385,-38.1173,1.25333); -v(2.63154,-41.8271,-5.87785); -v(-7.85312,-41.1675,-5.87785); -v(-7.62684,-39.9813,-3.68125); -v(2.63154,-41.8271,-5.87785); -v(-8.17465,-42.853,-7.70513); -v(-7.85312,-41.1675,-5.87785); -v(42.2552,10.8493,7.70513); -v(45.7422,-1.12036e-14,9.04827); -v(44.3051,11.3756,9.04827); -v(42.2552,10.8493,7.70513); -v(43.6258,-1.06852e-14,7.70513); -v(45.7422,-1.12036e-14,9.04827); -v(2.63154,-41.8271,-5.87785); -v(-7.62684,-39.9813,-3.68125); -v(2.55571,-40.6219,-3.68125); -v(-41.5794,5.25269,5.87785); -v(-38.9668,15.428,5.87785); -v(-43.2818,5.46776,7.70513); -v(-41.5794,5.25269,5.87785); -v(-37.844,14.9835,3.68125); -v(-38.9668,15.428,5.87785); -v(-20.4911,-43.5459,-9.82287); -v(-30.6768,-37.0819,-9.82287); -v(-29.1572,-35.245,-9.04827); -v(-20.4911,-43.5459,-9.82287); -v(-29.1572,-35.245,-9.04827); -v(-19.4761,-41.3888,-9.04827); -v(3.68976,58.6471,4.81754); -v(18.4439,56.7646,2.4869); -v(3.7477,59.5681,2.4869); -v(-20.4911,-43.5459,-9.82287); -v(-32.2714,-39.0095,-9.98027); -v(-30.6768,-37.0819,-9.82287); -v(3.68976,58.6471,4.81754); -v(18.1588,55.887,4.81754); -v(18.4439,56.7646,2.4869); -v(-32.4245,23.5578,-1.25333); -v(-25.5472,30.8813,-1.25333); -v(-32.4245,23.5578,1.25333); -v(-44.7858,-32.5388,-8.44328); -v(-49.362,-19.5438,-9.51056); -v(-42.9509,-31.2056,-9.51056); -v(-32.4245,23.5578,-1.25333); -v(-25.9446,31.3616,-3.68125); -v(-25.5472,30.8813,-1.25333); -v(-44.7858,-32.5388,-8.44328); -v(-51.4708,-20.3787,-8.44328); -v(-49.362,-19.5438,-9.51056); -v(-44.7858,-32.5388,-8.44328); -v(-53.2666,-21.0897,-6.84547); -v(-51.4708,-20.3787,-8.44328); -v(-59.2152,-7.48062,-2.4869); -v(-59.5269,-7.51999,-2.44929e-15); -v(-59.5269,7.51999,-2.44929e-15); -v(-18.5749,39.4738,-7.70513); -v(-8.17465,42.853,-7.70513); -v(-17.8443,37.9211,-5.87785); -v(-18.5749,39.4738,-7.70513); -v(-8.57123,44.932,-9.04827); -v(-8.17465,42.853,-7.70513); -v(-59.2152,-7.48062,-2.4869); -v(-59.5269,7.51999,-2.44929e-15); -v(-59.2152,7.48062,-2.4869); -v(-59.2152,-7.48062,-2.4869); -v(-59.2152,7.48062,-2.4869); -v(-58.2997,7.36496,-4.81754); -v(-59.2152,-7.48062,-2.4869); -v(-58.2997,7.36496,-4.81754); -v(-58.2997,-7.36496,-4.81754); -v(44.3051,-11.3756,9.04827); -v(42.1733,-23.185,9.82287); -v(46.6142,-11.9685,9.82287); -v(28.4471,44.8255,9.51056); -v(38.7011,36.3427,9.51056); -v(29.6624,46.7405,8.44328); -v(44.3051,-11.3756,9.04827); -v(40.0842,-22.0365,9.04827); -v(42.1733,-23.185,9.82287); -v(44.3051,-11.3756,9.04827); -v(48.1262,-1.17875e-14,9.82287); -v(45.7422,-1.12036e-14,9.04827); -v(3.17895,50.528,-9.98027); -v(15.6449,48.15,-9.98027); -v(3.02187,48.0312,-9.82287); -v(3.17895,50.528,-9.98027); -v(16.4058,50.4918,-9.51056); -v(15.6449,48.15,-9.98027); -v(44.3051,-11.3756,9.04827); -v(46.6142,-11.9685,9.82287); -v(48.1262,-1.17875e-14,9.82287); -v(40.0842,22.0365,9.04827); -v(46.6142,11.9685,9.82287); -v(42.1733,23.185,9.82287); -v(29.6707,-27.8626,3.68125); -v(21.8093,-34.366,3.68125); -v(22.4564,-35.3856,5.87785); -v(29.6707,-27.8626,3.68125); -v(22.4564,-35.3856,5.87785); -v(30.551,-28.6893,5.87785); -v(40.0842,22.0365,9.04827); -v(44.3051,11.3756,9.04827); -v(46.6142,11.9685,9.82287); -v(-24.3928,-51.8373,6.84547); -v(-36.5178,-44.1425,6.84547); -v(-37.457,-45.2777,4.81754); -v(29.6707,-27.8626,3.68125); -v(21.4753,-33.8397,1.25333); -v(21.8093,-34.366,3.68125); -v(-24.3928,-51.8373,6.84547); -v(-37.457,-45.2777,4.81754); -v(-25.0201,-53.1704,4.81754); -v(-11.184,58.6286,2.4869); -v(3.7477,59.5681,2.4869); -v(3.76743,59.8816,-2.44929e-15); -v(-11.184,58.6286,2.4869); -v(3.76743,59.8816,-2.44929e-15); -v(-11.2429,58.9372,-2.44929e-15); -v(30.6973,48.3713,-6.84547); -v(41.7624,39.2175,-6.84547); -v(40.3544,37.8953,-8.44328); -v(17.1066,52.6488,8.44328); -v(29.6624,46.7405,8.44328); -v(30.6973,48.3713,6.84547); -v(12.5777,-38.7101,-3.68125); -v(2.55571,-40.6219,-3.68125); -v(12.385,-38.1173,-1.25333); -v(30.6973,48.3713,-6.84547); -v(40.3544,37.8953,-8.44328); -v(29.6624,46.7405,-8.44328); -v(17.1066,52.6488,8.44328); -v(30.6973,48.3713,6.84547); -v(17.7035,54.4857,6.84547); -v(30.6973,48.3713,-6.84547); -v(42.8364,40.2261,-4.81754); -v(41.7624,39.2175,-6.84547); -v(-8.57123,-44.932,-9.04827); -v(-19.4761,-41.3888,-9.04827); -v(-8.17465,-42.853,-7.70513); -v(17.1066,52.6488,8.44328); -v(28.4471,44.8255,9.51056); -v(29.6624,46.7405,8.44328); -v(-40.9588,-29.7583,9.98027); -v(-47.0726,-18.6374,9.98027); -v(-49.362,-19.5438,9.51056); -v(-40.9588,-29.7583,9.98027); -v(-44.7466,-17.7164,9.82287); -v(-47.0726,-18.6374,9.98027); -v(-40.9588,-29.7583,9.98027); -v(-49.362,-19.5438,9.51056); -v(-42.9509,-31.2056,9.51056); -v(35.0825,32.9446,9.82287); -v(42.1733,23.185,9.82287); -v(36.9062,34.6572,9.98027); -v(-43.2818,-5.46776,7.70513); -v(-41.5794,5.25269,5.87785); -v(-43.2818,5.46776,7.70513); -v(35.0825,32.9446,9.82287); -v(40.0842,22.0365,9.04827); -v(42.1733,23.185,9.82287); -v(-33.8409,-40.9067,-9.51056); -v(-42.9509,-31.2056,-9.51056); -v(-32.2714,-39.0095,-9.98027); -v(40.5932,10.4226,5.87785); -v(43.6258,-1.06852e-14,7.70513); -v(42.2552,10.8493,7.70513); -v(-43.2818,-5.46776,7.70513); -v(-43.2818,5.46776,7.70513); -v(-45.3815,5.73302,9.04827); -v(-43.2818,-5.46776,7.70513); -v(-45.3815,5.73302,9.04827); -v(-45.3815,-5.73302,9.04827); -v(-54.6365,-21.6321,-4.81754); -v(-58.2997,-7.36496,-4.81754); -v(-53.2666,-21.0897,-6.84547); -v(40.5932,10.4226,5.87785); -v(41.9098,-1.02649e-14,5.87785); -v(43.6258,-1.06852e-14,7.70513); -v(-37.2644,14.754,1.25333); -v(-32.4245,23.5578,1.25333); -v(-37.844,14.9835,3.68125); -v(36.7259,-20.1902,5.87785); -v(29.6707,-27.8626,3.68125); -v(30.551,-28.6893,5.87785); -v(36.7259,-20.1902,5.87785); -v(30.551,-28.6893,5.87785); -v(38.2295,-21.0169,7.70513); -v(21.4753,-33.8397,-1.25333); -v(12.5777,-38.7101,-3.68125); -v(12.385,-38.1173,-1.25333); -v(3.59725,57.1766,6.84547); -v(17.7035,54.4857,6.84547); -v(18.1588,55.887,4.81754); -v(-37.2644,14.754,1.25333); -v(-32.4245,23.5578,-1.25333); -v(-32.4245,23.5578,1.25333); -v(3.59725,57.1766,6.84547); -v(18.1588,55.887,4.81754); -v(3.68976,58.6471,4.81754); -v(-26.7143,32.2921,-5.87785); -v(-18.5749,39.4738,-7.70513); -v(-17.8443,37.9211,-5.87785); -v(21.4753,-33.8397,-1.25333); -v(12.385,-38.1173,-1.25333); -v(21.4753,-33.8397,1.25333); -v(-26.7143,32.2921,-5.87785); -v(-17.8443,37.9211,-5.87785); -v(-17.3302,36.8285,-3.68125); -v(-26.7143,32.2921,-5.87785); -v(-17.3302,36.8285,-3.68125); -v(-25.9446,31.3616,-3.68125); -v(2.73928,-43.5397,-7.70513); -v(-8.57123,-44.932,-9.04827); -v(-8.17465,-42.853,-7.70513); -v(27.1278,42.7466,9.98027); -v(36.9062,34.6572,9.98027); -v(38.7011,36.3427,9.51056); -v(-9.01795,47.2737,-9.82287); -v(2.87218,45.6519,-9.04827); -v(-8.57123,44.932,-9.04827); -v(-9.01795,47.2737,-9.82287); -v(3.17895,50.528,-9.98027); -v(3.02187,48.0312,-9.82287); -v(2.73928,-43.5397,-7.70513); -v(-8.17465,-42.853,-7.70513); -v(2.63154,-41.8271,-5.87785); -v(-9.01795,47.2737,-9.82287); -v(3.02187,48.0312,-9.82287); -v(2.87218,45.6519,-9.04827); -v(-21.5563,-45.8095,-9.98027); -v(-33.8409,-40.9067,-9.51056); -v(-32.2714,-39.0095,-9.98027); -v(27.1278,42.7466,9.98027); -v(38.7011,36.3427,9.51056); -v(28.4471,44.8255,9.51056); -v(-11.0111,-57.7222,4.81754); -v(-25.0201,-53.1704,4.81754); -v(-25.413,-54.0054,2.4869); -v(-21.5563,-45.8095,-9.98027); -v(-32.2714,-39.0095,-9.98027); -v(-20.4911,-43.5459,-9.82287); -v(-46.3483,-33.674,-6.84547); -v(-53.2666,-21.0897,-6.84547); -v(-44.7858,-32.5388,-8.44328); -v(-11.0111,-57.7222,4.81754); -v(-25.413,-54.0054,2.4869); -v(-11.184,-58.6286,2.4869); -v(38.2295,21.0169,7.70513); -v(44.3051,11.3756,9.04827); -v(40.0842,22.0365,9.04827); -v(-46.3483,-33.674,-6.84547); -v(-54.6365,-21.6321,-4.81754); -v(-53.2666,-21.0897,-6.84547); -v(38.2295,21.0169,7.70513); -v(42.2552,10.8493,7.70513); -v(44.3051,11.3756,9.04827); -v(42.2552,-10.8493,7.70513); -v(44.3051,-11.3756,9.04827); -v(45.7422,-1.12036e-14,9.04827); -v(42.2552,-10.8493,7.70513); -v(45.7422,-1.12036e-14,9.04827); -v(43.6258,-1.06852e-14,7.70513); -v(17.1066,52.6488,-8.44328); -v(30.6973,48.3713,-6.84547); -v(29.6624,46.7405,-8.44328); -v(-11.0111,57.7222,4.81754); -v(3.68976,58.6471,4.81754); -v(3.7477,59.5681,2.4869); -v(17.1066,52.6488,-8.44328); -v(28.4471,44.8255,-9.51056); -v(16.4058,50.4918,-9.51056); -v(-11.0111,57.7222,4.81754); -v(3.7477,59.5681,2.4869); -v(-11.184,58.6286,2.4869); -v(17.1066,52.6488,-8.44328); -v(29.6624,46.7405,-8.44328); -v(28.4471,44.8255,-9.51056); -v(42.2552,-10.8493,7.70513); -v(40.0842,-22.0365,9.04827); -v(44.3051,-11.3756,9.04827); -v(42.2552,-10.8493,7.70513); -v(38.2295,-21.0169,7.70513); -v(40.0842,-22.0365,9.04827); -v(29.2162,-27.4359,1.25333); -v(21.4753,-33.8397,1.25333); -v(29.6707,-27.8626,3.68125); -v(-33.8409,-40.9067,9.51056); -v(-42.9509,-31.2056,9.51056); -v(-35.2867,-42.6543,8.44328); -v(12.9508,-39.8586,-5.87785); -v(2.55571,-40.6219,-3.68125); -v(12.5777,-38.7101,-3.68125); -v(12.9508,-39.8586,-5.87785); -v(2.73928,-43.5397,-7.70513); -v(2.63154,-41.8271,-5.87785); -v(43.5091,40.8578,-2.4869); -v(43.7381,41.0728,-2.44929e-15); -v(52.5784,28.9052,-2.44929e-15); -v(43.5091,40.8578,-2.4869); -v(32.1496,50.6597,-2.44929e-15); -v(43.7381,41.0728,-2.44929e-15); -v(43.5091,40.8578,-2.4869); -v(52.5784,28.9052,-2.44929e-15); -v(52.3031,28.7539,-2.4869); -v(43.5091,40.8578,-2.4869); -v(52.3031,28.7539,-2.4869); -v(51.4945,28.3093,-4.81754); -v(16.4058,50.4918,9.51056); -v(28.4471,44.8255,9.51056); -v(17.1066,52.6488,8.44328); -v(43.5091,40.8578,-2.4869); -v(51.4945,28.3093,-4.81754); -v(42.8364,40.2261,-4.81754); -v(33.3446,31.3127,9.04827); -v(40.0842,22.0365,9.04827); -v(35.0825,32.9446,9.82287); -v(12.9508,-39.8586,-5.87785); -v(2.63154,-41.8271,-5.87785); -v(2.55571,-40.6219,-3.68125); -v(-9.01795,-47.2737,-9.82287); -v(-19.4761,-41.3888,-9.04827); -v(-8.57123,-44.932,-9.04827); -v(-9.01795,-47.2737,-9.82287); -v(-21.5563,-45.8095,-9.98027); -v(-20.4911,-43.5459,-9.82287); -v(-9.01795,-47.2737,-9.82287); -v(-20.4911,-43.5459,-9.82287); -v(-19.4761,-41.3888,-9.04827); -v(-42.53,-16.8388,9.04827); -v(-45.3815,-5.73302,9.04827); -v(-44.7466,-17.7164,9.82287); -v(-35.2867,-42.6543,-8.44328); -v(-46.3483,-33.674,-6.84547); -v(-44.7858,-32.5388,-8.44328); -v(-35.2867,-42.6543,-8.44328); -v(-42.9509,-31.2056,-9.51056); -v(-33.8409,-40.9067,-9.51056); -v(39.4235,10.1222,3.68125); -v(41.9098,-1.02649e-14,5.87785); -v(40.5932,10.4226,5.87785); -v(-40.3813,5.10134,3.68125); -v(-37.2644,14.754,1.25333); -v(-37.844,14.9835,3.68125); -v(39.4235,10.1222,3.68125); -v(40.7022,-9.96917e-15,3.68125); -v(41.9098,-1.02649e-14,5.87785); -v(-35.2867,-42.6543,-8.44328); -v(-44.7858,-32.5388,-8.44328); -v(-42.9509,-31.2056,-9.51056); -v(39.4235,10.1222,3.68125); -v(40.0789,-9.81649e-15,1.25333); -v(40.7022,-9.96917e-15,3.68125); -v(-40.3813,5.10134,3.68125); -v(-37.844,14.9835,3.68125); -v(-41.5794,5.25269,5.87785); -v(-55.4945,-21.9718,-2.4869); -v(-59.2152,-7.48062,-2.4869); -v(-58.2997,-7.36496,-4.81754); -v(-55.4945,-21.9718,-2.4869); -v(-55.7866,-22.0875,-2.44929e-15); -v(-59.5269,-7.51999,-2.44929e-15); -v(-55.4945,-21.9718,-2.4869); -v(-48.541,-35.2671,-2.44929e-15); -v(-55.7866,-22.0875,-2.44929e-15); -v(-55.4945,-21.9718,-2.4869); -v(-58.2997,-7.36496,-4.81754); -v(-54.6365,-21.6321,-4.81754); -v(-25.413,54.0054,2.4869); -v(-11.184,58.6286,2.4869); -v(-11.2429,58.9372,-2.44929e-15); -v(-55.4945,-21.9718,-2.4869); -v(-59.5269,-7.51999,-2.44929e-15); -v(-59.2152,-7.48062,-2.4869); -v(-25.413,54.0054,2.4869); -v(-11.2429,58.9372,-2.44929e-15); -v(-25.5468,54.2896,-2.44929e-15); -v(35.6676,-19.6085,3.68125); -v(29.6707,-27.8626,3.68125); -v(36.7259,-20.1902,5.87785); -v(-32.9288,23.9242,-3.68125); -v(-25.9446,31.3616,-3.68125); -v(-32.4245,23.5578,-1.25333); -v(35.6676,-19.6085,3.68125); -v(29.2162,-27.4359,1.25333); -v(29.6707,-27.8626,3.68125); -v(3.47597,55.249,8.44328); -v(16.4058,50.4918,9.51056); -v(17.1066,52.6488,8.44328); -v(-19.4761,41.3888,-9.04827); -v(-8.57123,44.932,-9.04827); -v(-18.5749,39.4738,-7.70513); -v(3.47597,55.249,8.44328); -v(17.7035,54.4857,6.84547); -v(3.59725,57.1766,6.84547); -v(3.47597,55.249,8.44328); -v(17.1066,52.6488,8.44328); -v(17.7035,54.4857,6.84547); -v(21.8093,-34.366,-3.68125); -v(12.5777,-38.7101,-3.68125); -v(21.4753,-33.8397,-1.25333); -v(3.7477,-59.5681,2.4869); -v(-11.2429,-58.9372,-2.44929e-15); -v(3.76743,-59.8816,-2.44929e-15); -v(3.7477,-59.5681,2.4869); -v(-11.184,-58.6286,2.4869); -v(-11.2429,-58.9372,-2.44929e-15); -v(3.33356,52.9854,-9.51056); -v(16.4058,50.4918,-9.51056); -v(3.17895,50.528,-9.98027); -v(2.87218,-45.6519,-9.04827); -v(-8.57123,-44.932,-9.04827); -v(2.73928,-43.5397,-7.70513); -v(25.7873,40.6343,9.82287); -v(35.0825,32.9446,9.82287); -v(36.9062,34.6572,9.98027); -v(25.7873,40.6343,9.82287); -v(36.9062,34.6572,9.98027); -v(27.1278,42.7466,9.98027); -v(-23.5704,-50.0897,8.44328); -v(-35.2867,-42.6543,8.44328); -v(-36.5178,-44.1425,6.84547); -v(-22.6047,-48.0374,-9.51056); -v(-33.8409,-40.9067,-9.51056); -v(-21.5563,-45.8095,-9.98027); -v(36.7259,20.1902,5.87785); -v(42.2552,10.8493,7.70513); -v(38.2295,21.0169,7.70513); -v(-47.5403,-34.5401,-4.81754); -v(-54.6365,-21.6321,-4.81754); -v(-46.3483,-33.674,-6.84547); -v(-23.5704,-50.0897,8.44328); -v(-36.5178,-44.1425,6.84547); -v(-24.3928,-51.8373,6.84547); -v(36.7259,20.1902,5.87785); -v(40.5932,10.4226,5.87785); -v(42.2552,10.8493,7.70513); -v(-23.5704,-50.0897,8.44328); -v(-33.8409,-40.9067,9.51056); -v(-35.2867,-42.6543,8.44328); -v(-10.735,56.2749,6.84547); -v(3.68976,58.6471,4.81754); -v(-11.0111,57.7222,4.81754); -v(40.5932,-10.4226,5.87785); -v(42.2552,-10.8493,7.70513); -v(43.6258,-1.06852e-14,7.70513); -v(31.4868,49.6153,-4.81754); -v(42.8364,40.2261,-4.81754); -v(30.6973,48.3713,-6.84547); -v(40.5932,-10.4226,5.87785); -v(43.6258,-1.06852e-14,7.70513); -v(41.9098,-1.02649e-14,5.87785); -v(40.5932,-10.4226,5.87785); -v(38.2295,-21.0169,7.70513); -v(42.2552,-10.8493,7.70513); -v(40.5932,-10.4226,5.87785); -v(36.7259,-20.1902,5.87785); -v(38.2295,-21.0169,7.70513); -v(-10.735,56.2749,6.84547); -v(3.59725,57.1766,6.84547); -v(3.68976,58.6471,4.81754); -v(-38.9349,-28.2879,9.82287); -v(-42.53,-16.8388,9.04827); -v(-44.7466,-17.7164,9.82287); -v(-38.9349,-28.2879,9.82287); -v(-44.7466,-17.7164,9.82287); -v(-40.9588,-29.7583,9.98027); -v(15.6449,48.15,9.98027); -v(28.4471,44.8255,9.51056); -v(16.4058,50.4918,9.51056); -v(15.6449,48.15,9.98027); -v(27.1278,42.7466,9.98027); -v(28.4471,44.8255,9.51056); -v(29.2162,-27.4359,-1.25333); -v(21.4753,-33.8397,-1.25333); -v(21.4753,-33.8397,1.25333); -v(29.2162,-27.4359,-1.25333); -v(21.4753,-33.8397,1.25333); -v(29.2162,-27.4359,1.25333); -v(15.6449,48.15,9.98027); -v(25.7873,40.6343,9.82287); -v(27.1278,42.7466,9.98027); -v(-41.5794,-5.25269,5.87785); -v(-40.3813,5.10134,3.68125); -v(-41.5794,5.25269,5.87785); -v(13.4811,-41.4906,-7.70513); -v(2.87218,-45.6519,-9.04827); -v(2.73928,-43.5397,-7.70513); -v(-41.5794,-5.25269,5.87785); -v(-41.5794,5.25269,5.87785); -v(-43.2818,-5.46776,7.70513); -v(13.4811,-41.4906,-7.70513); -v(2.73928,-43.5397,-7.70513); -v(12.9508,-39.8586,-5.87785); -v(31.8018,29.8639,7.70513); -v(36.7259,20.1902,5.87785); -v(38.2295,21.0169,7.70513); -v(31.8018,29.8639,7.70513); -v(40.0842,22.0365,9.04827); -v(33.3446,31.3127,9.04827); -v(-9.48672,-49.7311,-9.98027); -v(-21.5563,-45.8095,-9.98027); -v(-9.01795,-47.2737,-9.82287); -v(-37.2644,14.754,-1.25333); -v(-32.4245,23.5578,-1.25333); -v(-37.2644,14.754,1.25333); -v(31.8018,29.8639,7.70513); -v(38.2295,21.0169,7.70513); -v(40.0842,22.0365,9.04827); -v(-37.2644,14.754,-1.25333); -v(-32.9288,23.9242,-3.68125); -v(-32.4245,23.5578,-1.25333); -v(-9.48672,-49.7311,-9.98027); -v(-22.6047,-48.0374,-9.51056); -v(-21.5563,-45.8095,-9.98027); -v(-27.8081,33.6142,-7.70513); -v(-18.5749,39.4738,-7.70513); -v(-26.7143,32.2921,-5.87785); -v(38.8197,9.96721,1.25333); -v(40.0789,-9.81649e-15,1.25333); -v(39.4235,10.1222,3.68125); -v(-36.5178,-44.1425,-6.84547); -v(-46.3483,-33.674,-6.84547); -v(-35.2867,-42.6543,-8.44328); -v(-36.5178,-44.1425,-6.84547); -v(-47.5403,-34.5401,-4.81754); -v(-46.3483,-33.674,-6.84547); -v(-27.8081,33.6142,-7.70513); -v(-19.4761,41.3888,-9.04827); -v(-18.5749,39.4738,-7.70513); -v(-25.0201,53.1704,4.81754); -v(-11.184,58.6286,2.4869); -v(-25.413,54.0054,2.4869); -v(35.1214,-19.3081,1.25333); -v(29.2162,-27.4359,1.25333); -v(35.6676,-19.6085,3.68125); -v(35.1214,-19.3081,1.25333); -v(29.2162,-27.4359,-1.25333); -v(29.2162,-27.4359,1.25333); -v(-9.48672,49.7311,-9.98027); -v(3.17895,50.528,-9.98027); -v(-9.01795,47.2737,-9.82287); -v(22.4564,-35.3856,-5.87785); -v(12.9508,-39.8586,-5.87785); -v(12.5777,-38.7101,-3.68125); -v(-25.0201,53.1704,4.81754); -v(-11.0111,57.7222,4.81754); -v(-11.184,58.6286,2.4869); -v(-9.48672,49.7311,-9.98027); -v(3.33356,52.9854,-9.51056); -v(3.17895,50.528,-9.98027); -v(22.4564,-35.3856,-5.87785); -v(12.5777,-38.7101,-3.68125); -v(21.8093,-34.366,-3.68125); -v(22.4564,-35.3856,-5.87785); -v(13.4811,-41.4906,-7.70513); -v(12.9508,-39.8586,-5.87785); -v(-10.735,-56.2749,6.84547); -v(-24.3928,-51.8373,6.84547); -v(-25.0201,-53.1704,4.81754); -v(-10.735,-56.2749,6.84547); -v(-25.0201,-53.1704,4.81754); -v(-11.0111,-57.7222,4.81754); -v(3.02187,-48.0312,-9.82287); -v(-8.57123,-44.932,-9.04827); -v(2.87218,-45.6519,-9.04827); -v(3.02187,-48.0312,-9.82287); -v(-9.01795,-47.2737,-9.82287); -v(-8.57123,-44.932,-9.04827); -v(3.33356,52.9854,9.51056); -v(16.4058,50.4918,9.51056); -v(3.47597,55.249,8.44328); -v(17.7035,54.4857,-6.84547); -v(30.6973,48.3713,-6.84547); -v(17.1066,52.6488,-8.44328); -v(3.02187,-48.0312,-9.82287); -v(-9.48672,-49.7311,-9.98027); -v(-9.01795,-47.2737,-9.82287); -v(17.7035,54.4857,-6.84547); -v(31.4868,49.6153,-4.81754); -v(30.6973,48.3713,-6.84547); -v(-23.5704,-50.0897,-8.44328); -v(-33.8409,-40.9067,-9.51056); -v(-22.6047,-48.0374,-9.51056); -v(24.5099,38.6214,9.04827); -v(35.0825,32.9446,9.82287); -v(25.7873,40.6343,9.82287); -v(-23.5704,-50.0897,-8.44328); -v(-36.5178,-44.1425,-6.84547); -v(-35.2867,-42.6543,-8.44328); -v(-23.5704,-50.0897,-8.44328); -v(-35.2867,-42.6543,-8.44328); -v(-33.8409,-40.9067,-9.51056); -v(24.5099,38.6214,9.04827); -v(33.3446,31.3127,9.04827); -v(35.0825,32.9446,9.82287); -v(-32.2714,-39.0095,9.98027); -v(-38.9349,-28.2879,9.82287); -v(-40.9588,-29.7583,9.98027); -v(35.6676,19.6085,3.68125); -v(39.4235,10.1222,3.68125); -v(40.5932,10.4226,5.87785); -v(-48.2869,-35.0825,-2.4869); -v(-48.541,-35.2671,-2.44929e-15); -v(-55.4945,-21.9718,-2.4869); -v(-48.2869,-35.0825,-2.4869); -v(-55.4945,-21.9718,-2.4869); -v(-54.6365,-21.6321,-4.81754); -v(-32.2714,-39.0095,9.98027); -v(-42.9509,-31.2056,9.51056); -v(-33.8409,-40.9067,9.51056); -v(-48.2869,-35.0825,-2.4869); -v(-54.6365,-21.6321,-4.81754); -v(-47.5403,-34.5401,-4.81754); -v(39.4235,-10.1222,3.68125); -v(41.9098,-1.02649e-14,5.87785); -v(40.7022,-9.96917e-15,3.68125); -v(-32.2714,-39.0095,9.98027); -v(-40.9588,-29.7583,9.98027); -v(-42.9509,-31.2056,9.51056); -v(39.4235,-10.1222,3.68125); -v(40.5932,-10.4226,5.87785); -v(41.9098,-1.02649e-14,5.87785); -v(35.6676,19.6085,3.68125); -v(40.5932,10.4226,5.87785); -v(36.7259,20.1902,5.87785); -v(-40.5622,-16.0597,7.70513); -v(-43.2818,-5.46776,7.70513); -v(-45.3815,-5.73302,9.04827); -v(39.4235,-10.1222,3.68125); -v(40.7022,-9.96917e-15,3.68125); -v(40.0789,-9.81649e-15,1.25333); -v(35.6676,19.6085,3.68125); -v(38.8197,9.96721,1.25333); -v(39.4235,10.1222,3.68125); -v(39.4235,-10.1222,3.68125); -v(35.6676,-19.6085,3.68125); -v(36.7259,-20.1902,5.87785); -v(-40.5622,-16.0597,7.70513); -v(-45.3815,-5.73302,9.04827); -v(-42.53,-16.8388,9.04827); -v(39.4235,-10.1222,3.68125); -v(36.7259,-20.1902,5.87785); -v(40.5932,-10.4226,5.87785); -v(39.4235,-10.1222,3.68125); -v(35.1214,-19.3081,1.25333); -v(35.6676,-19.6085,3.68125); -v(-38.0452,45.9887,2.4869); -v(-25.413,54.0054,2.4869); -v(-25.5468,54.2896,-2.44929e-15); -v(-38.0452,45.9887,2.4869); -v(-25.5468,54.2896,-2.44929e-15); -v(-38.2454,46.2308,-2.44929e-15); -v(29.6707,-27.8626,-3.68125); -v(21.4753,-33.8397,-1.25333); -v(29.2162,-27.4359,-1.25333); -v(-40.5622,-16.0597,7.70513); -v(-41.5794,-5.25269,5.87785); -v(-43.2818,-5.46776,7.70513); -v(29.6707,-27.8626,-3.68125); -v(21.8093,-34.366,-3.68125); -v(21.4753,-33.8397,-1.25333); -v(-10.3731,54.3777,8.44328); -v(3.59725,57.1766,6.84547); -v(-10.735,56.2749,6.84547); -v(-10.3731,54.3777,8.44328); -v(3.33356,52.9854,9.51056); -v(3.47597,55.249,8.44328); -v(-10.3731,54.3777,8.44328); -v(3.47597,55.249,8.44328); -v(3.59725,57.1766,6.84547); -v(-39.7628,5.02321,1.25333); -v(-37.2644,14.754,1.25333); -v(-40.3813,5.10134,3.68125); -v(-39.7628,5.02321,1.25333); -v(-37.2644,14.754,-1.25333); -v(-37.2644,14.754,1.25333); -v(14.1351,-43.5034,-9.04827); -v(2.87218,-45.6519,-9.04827); -v(13.4811,-41.4906,-7.70513); -v(-33.9058,24.634,-5.87785); -v(-26.7143,32.2921,-5.87785); -v(-25.9446,31.3616,-3.68125); -v(-33.9058,24.634,-5.87785); -v(-25.9446,31.3616,-3.68125); -v(-32.9288,23.9242,-3.68125); -v(-9.94811,-52.1498,-9.51056); -v(-22.6047,-48.0374,-9.51056); -v(-9.48672,-49.7311,-9.98027); -v(14.8718,45.7707,9.82287); -v(25.7873,40.6343,9.82287); -v(15.6449,48.15,9.98027); -v(-33.9058,24.634,-5.87785); -v(-27.8081,33.6142,-7.70513); -v(-26.7143,32.2921,-5.87785); -v(14.8718,45.7707,9.82287); -v(24.5099,38.6214,9.04827); -v(25.7873,40.6343,9.82287); -v(-37.457,-45.2777,-4.81754); -v(-47.5403,-34.5401,-4.81754); -v(-36.5178,-44.1425,-6.84547); -v(30.551,28.6893,5.87785); -v(36.7259,20.1902,5.87785); -v(31.8018,29.8639,7.70513); -v(-20.4911,43.5459,-9.82287); -v(-8.57123,44.932,-9.04827); -v(-19.4761,41.3888,-9.04827); -v(-20.4911,43.5459,-9.82287); -v(-9.48672,49.7311,-9.98027); -v(-9.01795,47.2737,-9.82287); -v(-20.4911,43.5459,-9.82287); -v(-9.01795,47.2737,-9.82287); -v(-8.57123,44.932,-9.04827); -v(30.551,28.6893,5.87785); -v(35.6676,19.6085,3.68125); -v(36.7259,20.1902,5.87785); -v(3.68976,-58.6471,4.81754); -v(-11.0111,-57.7222,4.81754); -v(-11.184,-58.6286,2.4869); -v(35.1214,-19.3081,-1.25333); -v(29.6707,-27.8626,-3.68125); -v(29.2162,-27.4359,-1.25333); -v(35.1214,-19.3081,-1.25333); -v(29.2162,-27.4359,-1.25333); -v(35.1214,-19.3081,1.25333); -v(38.8197,9.96721,-1.25333); -v(40.0789,-9.81649e-15,1.25333); -v(38.8197,9.96721,1.25333); -v(23.3759,-36.8344,-7.70513); -v(14.1351,-43.5034,-9.04827); -v(13.4811,-41.4906,-7.70513); -v(3.68976,-58.6471,4.81754); -v(-11.184,-58.6286,2.4869); -v(3.7477,-59.5681,2.4869); -v(38.8197,9.96721,-1.25333); -v(40.0789,-9.81649e-15,-1.25333); -v(40.0789,-9.81649e-15,1.25333); -v(3.47597,55.249,-8.44328); -v(17.1066,52.6488,-8.44328); -v(16.4058,50.4918,-9.51056); -v(3.47597,55.249,-8.44328); -v(16.4058,50.4918,-9.51056); -v(3.33356,52.9854,-9.51056); -v(23.3759,-36.8344,-7.70513); -v(13.4811,-41.4906,-7.70513); -v(22.4564,-35.3856,-5.87785); -v(-24.3928,51.8373,6.84547); -v(-11.0111,57.7222,4.81754); -v(-25.0201,53.1704,4.81754); -v(3.47597,55.249,-8.44328); -v(17.7035,54.4857,-6.84547); -v(17.1066,52.6488,-8.44328); -v(3.17895,-50.528,-9.98027); -v(-9.48672,-49.7311,-9.98027); -v(3.02187,-48.0312,-9.82287); -v(3.17895,-50.528,-9.98027); -v(-9.94811,-52.1498,-9.51056); -v(-9.48672,-49.7311,-9.98027); -v(-24.3928,51.8373,6.84547); -v(-10.735,56.2749,6.84547); -v(-11.0111,57.7222,4.81754); -v(-24.3928,-51.8373,-6.84547); -v(-37.457,-45.2777,-4.81754); -v(-36.5178,-44.1425,-6.84547); -v(-22.6047,-48.0374,9.51056); -v(-33.8409,-40.9067,9.51056); -v(-23.5704,-50.0897,8.44328); -v(3.17895,50.528,9.98027); -v(15.6449,48.15,9.98027); -v(16.4058,50.4918,9.51056); -v(-24.3928,-51.8373,-6.84547); -v(-36.5178,-44.1425,-6.84547); -v(-23.5704,-50.0897,-8.44328); -v(31.9813,50.3944,-2.4869); -v(32.1496,50.6597,-2.44929e-15); -v(43.5091,40.8578,-2.4869); -v(38.8197,-9.96721,1.25333); -v(35.1214,-19.3081,1.25333); -v(39.4235,-10.1222,3.68125); -v(31.9813,50.3944,-2.4869); -v(43.5091,40.8578,-2.4869); -v(42.8364,40.2261,-4.81754); -v(38.8197,-9.96721,1.25333); -v(39.4235,-10.1222,3.68125); -v(40.0789,-9.81649e-15,1.25333); -v(31.9813,50.3944,-2.4869); -v(42.8364,40.2261,-4.81754); -v(31.4868,49.6153,-4.81754); -v(3.17895,50.528,9.98027); -v(16.4058,50.4918,9.51056); -v(3.33356,52.9854,9.51056); -v(3.17895,50.528,9.98027); -v(14.8718,45.7707,9.82287); -v(15.6449,48.15,9.98027); -v(30.551,-28.6893,-5.87785); -v(21.8093,-34.366,-3.68125); -v(29.6707,-27.8626,-3.68125); -v(-37.0062,-26.8866,9.04827); -v(-42.53,-16.8388,9.04827); -v(-38.9349,-28.2879,9.82287); -v(23.3759,36.8344,7.70513); -v(33.3446,31.3127,9.04827); -v(24.5099,38.6214,9.04827); -v(23.3759,36.8344,7.70513); -v(31.8018,29.8639,7.70513); -v(33.3446,31.3127,9.04827); -v(30.551,-28.6893,-5.87785); -v(22.4564,-35.3856,-5.87785); -v(21.8093,-34.366,-3.68125); -v(14.8718,-45.7707,-9.82287); -v(3.17895,-50.528,-9.98027); -v(3.02187,-48.0312,-9.82287); -v(14.8718,-45.7707,-9.82287); -v(3.02187,-48.0312,-9.82287); -v(2.87218,-45.6519,-9.04827); -v(-40.3813,-5.10134,3.68125); -v(-40.3813,5.10134,3.68125); -v(-41.5794,-5.25269,5.87785); -v(14.8718,-45.7707,-9.82287); -v(2.87218,-45.6519,-9.04827); -v(14.1351,-43.5034,-9.04827); -v(35.1214,19.3081,1.25333); -v(38.8197,9.96721,1.25333); -v(35.6676,19.6085,3.68125); -v(-40.3813,-5.10134,3.68125); -v(-39.7628,5.02321,1.25333); -v(-40.3813,5.10134,3.68125); -v(-10.3731,-54.3777,-8.44328); -v(-22.6047,-48.0374,-9.51056); -v(-9.94811,-52.1498,-9.51056); -v(-10.3731,-54.3777,-8.44328); -v(-24.3928,-51.8373,-6.84547); -v(-23.5704,-50.0897,-8.44328); -v(-37.844,14.9835,-3.68125); -v(-32.9288,23.9242,-3.68125); -v(-37.2644,14.754,-1.25333); -v(-37.457,45.2777,4.81754); -v(-25.0201,53.1704,4.81754); -v(-25.413,54.0054,2.4869); -v(-37.457,45.2777,4.81754); -v(-25.413,54.0054,2.4869); -v(-38.0452,45.9887,2.4869); -v(-10.3731,-54.3777,-8.44328); -v(-23.5704,-50.0897,-8.44328); -v(-22.6047,-48.0374,-9.51056); -v(-38.0452,-45.9887,-2.4869); -v(-38.2454,-46.2308,-2.44929e-15); -v(-48.541,-35.2671,-2.44929e-15); -v(-38.0452,-45.9887,-2.4869); -v(-48.541,-35.2671,-2.44929e-15); -v(-48.2869,-35.0825,-2.4869); -v(-38.0452,-45.9887,-2.4869); -v(-47.5403,-34.5401,-4.81754); -v(-37.457,-45.2777,-4.81754); -v(-29.1572,35.245,-9.04827); -v(-19.4761,41.3888,-9.04827); -v(-27.8081,33.6142,-7.70513); -v(-38.0452,-45.9887,-2.4869); -v(-48.2869,-35.0825,-2.4869); -v(-47.5403,-34.5401,-4.81754); -v(35.6676,-19.6085,-3.68125); -v(29.6707,-27.8626,-3.68125); -v(35.1214,-19.3081,-1.25333); -v(-9.94811,52.1498,9.51056); -v(3.33356,52.9854,9.51056); -v(-10.3731,54.3777,8.44328); -v(18.4439,-56.7646,2.4869); -v(3.7477,-59.5681,2.4869); -v(3.76743,-59.8816,-2.44929e-15); -v(18.4439,-56.7646,2.4869); -v(3.76743,-59.8816,-2.44929e-15); -v(18.541,-57.0634,-2.44929e-15); -v(24.5099,-38.6214,-9.04827); -v(14.1351,-43.5034,-9.04827); -v(23.3759,-36.8344,-7.70513); -v(-9.94811,52.1498,-9.51056); -v(3.33356,52.9854,-9.51056); -v(-9.48672,49.7311,-9.98027); -v(14.1351,43.5034,9.04827); -v(24.5099,38.6214,9.04827); -v(14.8718,45.7707,9.82287); -v(3.33356,-52.9854,-9.51056); -v(-9.94811,-52.1498,-9.51056); -v(3.17895,-50.528,-9.98027); -v(18.1588,55.887,-4.81754); -v(31.4868,49.6153,-4.81754); -v(17.7035,54.4857,-6.84547); -v(29.6707,27.8626,3.68125); -v(35.1214,19.3081,1.25333); -v(35.6676,19.6085,3.68125); -v(-10.3731,-54.3777,8.44328); -v(-22.6047,-48.0374,9.51056); -v(-23.5704,-50.0897,8.44328); -v(29.6707,27.8626,3.68125); -v(35.6676,19.6085,3.68125); -v(30.551,28.6893,5.87785); -v(-25.0201,-53.1704,-4.81754); -v(-37.457,-45.2777,-4.81754); -v(-24.3928,-51.8373,-6.84547); -v(38.8197,-9.96721,-1.25333); -v(35.1214,-19.3081,-1.25333); -v(35.1214,-19.3081,1.25333); -v(38.8197,-9.96721,-1.25333); -v(35.1214,-19.3081,1.25333); -v(38.8197,-9.96721,1.25333); -v(39.4235,10.1222,-3.68125); -v(40.0789,-9.81649e-15,-1.25333); -v(38.8197,9.96721,-1.25333); -v(38.8197,-9.96721,-1.25333); -v(38.8197,-9.96721,1.25333); -v(40.0789,-9.81649e-15,1.25333); -v(-10.3731,-54.3777,8.44328); -v(-23.5704,-50.0897,8.44328); -v(-24.3928,-51.8373,6.84547); -v(38.8197,-9.96721,-1.25333); -v(40.0789,-9.81649e-15,1.25333); -v(40.0789,-9.81649e-15,-1.25333); -v(-10.3731,-54.3777,8.44328); -v(-24.3928,-51.8373,6.84547); -v(-10.735,-56.2749,6.84547); -v(39.4235,10.1222,-3.68125); -v(40.7022,-9.96917e-15,-3.68125); -v(40.0789,-9.81649e-15,-1.25333); -v(31.8018,-29.8639,-7.70513); -v(24.5099,-38.6214,-9.04827); -v(23.3759,-36.8344,-7.70513); -v(31.8018,-29.8639,-7.70513); -v(23.3759,-36.8344,-7.70513); -v(22.4564,-35.3856,-5.87785); -v(-48.2869,35.0825,2.4869); -v(-38.2454,46.2308,-2.44929e-15); -v(-48.541,35.2671,-2.44929e-15); -v(-48.2869,35.0825,2.4869); -v(-48.541,35.2671,-2.44929e-15); -v(-55.7866,22.0875,-2.44929e-15); -v(-30.6768,-37.0819,9.82287); -v(-37.0062,-26.8866,9.04827); -v(-38.9349,-28.2879,9.82287); -v(-30.6768,-37.0819,9.82287); -v(-38.9349,-28.2879,9.82287); -v(-32.2714,-39.0095,9.98027); -v(-48.2869,35.0825,2.4869); -v(-38.0452,45.9887,2.4869); -v(-38.2454,46.2308,-2.44929e-15); -v(-38.9668,-15.428,5.87785); -v(-40.3813,-5.10134,3.68125); -v(-41.5794,-5.25269,5.87785); -v(31.8018,-29.8639,-7.70513); -v(22.4564,-35.3856,-5.87785); -v(30.551,-28.6893,-5.87785); -v(15.6449,-48.15,-9.98027); -v(3.33356,-52.9854,-9.51056); -v(3.17895,-50.528,-9.98027); -v(-23.5704,50.0897,8.44328); -v(-9.94811,52.1498,9.51056); -v(-10.3731,54.3777,8.44328); -v(15.6449,-48.15,-9.98027); -v(3.17895,-50.528,-9.98027); -v(14.8718,-45.7707,-9.82287); -v(-23.5704,50.0897,8.44328); -v(-10.3731,54.3777,8.44328); -v(-10.735,56.2749,6.84547); -v(-38.9668,-15.428,5.87785); -v(-41.5794,-5.25269,5.87785); -v(-40.5622,-16.0597,7.70513); -v(-23.5704,50.0897,8.44328); -v(-10.735,56.2749,6.84547); -v(-24.3928,51.8373,6.84547); -v(-10.735,-56.2749,-6.84547); -v(-25.0201,-53.1704,-4.81754); -v(-24.3928,-51.8373,-6.84547); -v(-39.7628,5.02321,-1.25333); -v(-37.2644,14.754,-1.25333); -v(-39.7628,5.02321,1.25333); -v(-10.735,-56.2749,-6.84547); -v(-24.3928,-51.8373,-6.84547); -v(-10.3731,-54.3777,-8.44328); -v(-39.7628,5.02321,-1.25333); -v(-37.844,14.9835,-3.68125); -v(-37.2644,14.754,-1.25333); -v(36.7259,-20.1902,-5.87785); -v(29.6707,-27.8626,-3.68125); -v(35.6676,-19.6085,-3.68125); -v(3.02187,48.0312,9.82287); -v(14.8718,45.7707,9.82287); -v(3.17895,50.528,9.98027); -v(36.7259,-20.1902,-5.87785); -v(31.8018,-29.8639,-7.70513); -v(30.551,-28.6893,-5.87785); -v(3.02187,48.0312,9.82287); -v(14.1351,43.5034,9.04827); -v(14.8718,45.7707,9.82287); -v(36.7259,-20.1902,-5.87785); -v(30.551,-28.6893,-5.87785); -v(29.6707,-27.8626,-3.68125); -v(-35.294,25.6426,-7.70513); -v(-29.1572,35.245,-9.04827); -v(-27.8081,33.6142,-7.70513); -v(25.7873,-40.6343,-9.82287); -v(14.1351,-43.5034,-9.04827); -v(24.5099,-38.6214,-9.04827); -v(25.7873,-40.6343,-9.82287); -v(14.8718,-45.7707,-9.82287); -v(14.1351,-43.5034,-9.04827); -v(-35.294,25.6426,-7.70513); -v(-27.8081,33.6142,-7.70513); -v(-33.9058,24.634,-5.87785); -v(22.4564,35.3856,5.87785); -v(30.551,28.6893,5.87785); -v(31.8018,29.8639,7.70513); -v(25.7873,-40.6343,-9.82287); -v(15.6449,-48.15,-9.98027); -v(14.8718,-45.7707,-9.82287); -v(22.4564,35.3856,5.87785); -v(31.8018,29.8639,7.70513); -v(23.3759,36.8344,7.70513); -v(-21.5563,45.8095,-9.98027); -v(-9.94811,52.1498,-9.51056); -v(-9.48672,49.7311,-9.98027); -v(-21.5563,45.8095,-9.98027); -v(-9.48672,49.7311,-9.98027); -v(-20.4911,43.5459,-9.82287); -v(3.59725,-57.1766,6.84547); -v(-10.735,-56.2749,6.84547); -v(-11.0111,-57.7222,4.81754); -v(35.1214,19.3081,-1.25333); -v(38.8197,9.96721,1.25333); -v(35.1214,19.3081,1.25333); -v(3.47597,-55.249,-8.44328); -v(-9.94811,-52.1498,-9.51056); -v(3.33356,-52.9854,-9.51056); -v(35.1214,19.3081,-1.25333); -v(38.8197,9.96721,-1.25333); -v(38.8197,9.96721,1.25333); -v(3.47597,-55.249,-8.44328); -v(-10.735,-56.2749,-6.84547); -v(-10.3731,-54.3777,-8.44328); -v(3.59725,-57.1766,6.84547); -v(-11.0111,-57.7222,4.81754); -v(3.68976,-58.6471,4.81754); -v(3.47597,-55.249,-8.44328); -v(-10.3731,-54.3777,-8.44328); -v(-9.94811,-52.1498,-9.51056); -v(-25.413,-54.0054,-2.4869); -v(-38.2454,-46.2308,-2.44929e-15); -v(-38.0452,-45.9887,-2.4869); -v(-25.413,-54.0054,-2.4869); -v(-25.5468,-54.2896,-2.44929e-15); -v(-38.2454,-46.2308,-2.44929e-15); -v(-25.413,-54.0054,-2.4869); -v(-38.0452,-45.9887,-2.4869); -v(-37.457,-45.2777,-4.81754); -v(3.59725,57.1766,-6.84547); -v(17.7035,54.4857,-6.84547); -v(3.47597,55.249,-8.44328); -v(-25.413,-54.0054,-2.4869); -v(-37.457,-45.2777,-4.81754); -v(-25.0201,-53.1704,-4.81754); -v(39.4235,-10.1222,-3.68125); -v(38.8197,-9.96721,-1.25333); -v(40.0789,-9.81649e-15,-1.25333); -v(39.4235,-10.1222,-3.68125); -v(35.1214,-19.3081,-1.25333); -v(38.8197,-9.96721,-1.25333); -v(3.59725,57.1766,-6.84547); -v(18.1588,55.887,-4.81754); -v(17.7035,54.4857,-6.84547); -v(39.4235,-10.1222,-3.68125); -v(40.0789,-9.81649e-15,-1.25333); -v(40.7022,-9.96917e-15,-3.68125); -v(-21.5563,-45.8095,9.98027); -v(-33.8409,-40.9067,9.51056); -v(-22.6047,-48.0374,9.51056); -v(-36.5178,44.1425,6.84547); -v(-24.3928,51.8373,6.84547); -v(-25.0201,53.1704,4.81754); -v(39.4235,-10.1222,-3.68125); -v(35.6676,-19.6085,-3.68125); -v(35.1214,-19.3081,-1.25333); -v(-36.5178,44.1425,6.84547); -v(-25.0201,53.1704,4.81754); -v(-37.457,45.2777,4.81754); -v(33.3446,-31.3127,-9.04827); -v(24.5099,-38.6214,-9.04827); -v(31.8018,-29.8639,-7.70513); -v(-9.48672,49.7311,9.98027); -v(3.02187,48.0312,9.82287); -v(3.17895,50.528,9.98027); -v(-21.5563,-45.8095,9.98027); -v(-30.6768,-37.0819,9.82287); -v(-32.2714,-39.0095,9.98027); -v(-21.5563,-45.8095,9.98027); -v(-32.2714,-39.0095,9.98027); -v(-33.8409,-40.9067,9.51056); -v(-9.48672,49.7311,9.98027); -v(3.17895,50.528,9.98027); -v(3.33356,52.9854,9.51056); -v(16.4058,-50.4918,-9.51056); -v(3.33356,-52.9854,-9.51056); -v(15.6449,-48.15,-9.98027); -v(-9.48672,49.7311,9.98027); -v(3.33356,52.9854,9.51056); -v(-9.94811,52.1498,9.51056); -v(-35.294,-25.6426,7.70513); -v(-38.9668,-15.428,5.87785); -v(-40.5622,-16.0597,7.70513); -v(-35.294,-25.6426,7.70513); -v(-40.5622,-16.0597,7.70513); -v(-42.53,-16.8388,9.04827); -v(-35.294,-25.6426,7.70513); -v(-42.53,-16.8388,9.04827); -v(-37.0062,-26.8866,9.04827); -v(13.4811,41.4906,7.70513); -v(22.4564,35.3856,5.87785); -v(23.3759,36.8344,7.70513); -v(-11.0111,-57.7222,-4.81754); -v(-25.0201,-53.1704,-4.81754); -v(-10.735,-56.2749,-6.84547); -v(13.4811,41.4906,7.70513); -v(23.3759,36.8344,7.70513); -v(24.5099,38.6214,9.04827); -v(13.4811,41.4906,7.70513); -v(24.5099,38.6214,9.04827); -v(14.1351,43.5034,9.04827); -v(-39.7628,-5.02321,1.25333); -v(-39.7628,5.02321,-1.25333); -v(-39.7628,5.02321,1.25333); -v(38.2295,-21.0169,-7.70513); -v(33.3446,-31.3127,-9.04827); -v(31.8018,-29.8639,-7.70513); -v(-39.7628,-5.02321,1.25333); -v(-39.7628,5.02321,1.25333); -v(-40.3813,-5.10134,3.68125); -v(38.2295,-21.0169,-7.70513); -v(31.8018,-29.8639,-7.70513); -v(36.7259,-20.1902,-5.87785); -v(29.2162,27.4359,1.25333); -v(35.1214,19.3081,1.25333); -v(29.6707,27.8626,3.68125); -v(29.2162,27.4359,1.25333); -v(35.1214,19.3081,-1.25333); -v(35.1214,19.3081,1.25333); -v(-38.9668,15.428,-5.87785); -v(-32.9288,23.9242,-3.68125); -v(-37.844,14.9835,-3.68125); -v(27.1278,-42.7466,-9.98027); -v(16.4058,-50.4918,-9.51056); -v(15.6449,-48.15,-9.98027); -v(-38.9668,15.428,-5.87785); -v(-35.294,25.6426,-7.70513); -v(-33.9058,24.634,-5.87785); -v(27.1278,-42.7466,-9.98027); -v(15.6449,-48.15,-9.98027); -v(25.7873,-40.6343,-9.82287); -v(-38.9668,15.428,-5.87785); -v(-33.9058,24.634,-5.87785); -v(-32.9288,23.9242,-3.68125); -v(40.5932,10.4226,-5.87785); -v(40.7022,-9.96917e-15,-3.68125); -v(39.4235,10.1222,-3.68125); -v(40.5932,10.4226,-5.87785); -v(41.9098,-1.02649e-14,-5.87785); -v(40.7022,-9.96917e-15,-3.68125); -v(-30.6768,37.0819,-9.82287); -v(-19.4761,41.3888,-9.04827); -v(-29.1572,35.245,-9.04827); -v(3.59725,-57.1766,-6.84547); -v(-10.735,-56.2749,-6.84547); -v(3.47597,-55.249,-8.44328); -v(-30.6768,37.0819,-9.82287); -v(-21.5563,45.8095,-9.98027); -v(-20.4911,43.5459,-9.82287); -v(-30.6768,37.0819,-9.82287); -v(-20.4911,43.5459,-9.82287); -v(-19.4761,41.3888,-9.04827); -v(3.59725,-57.1766,-6.84547); -v(-11.0111,-57.7222,-4.81754); -v(-10.735,-56.2749,-6.84547); -v(-47.5403,34.5401,4.81754); -v(-37.457,45.2777,4.81754); -v(-38.0452,45.9887,2.4869); -v(40.5932,-10.4226,-5.87785); -v(40.7022,-9.96917e-15,-3.68125); -v(41.9098,-1.02649e-14,-5.87785); -v(40.5932,-10.4226,-5.87785); -v(36.7259,-20.1902,-5.87785); -v(35.6676,-19.6085,-3.68125); -v(-47.5403,34.5401,4.81754); -v(-38.0452,45.9887,2.4869); -v(-48.2869,35.0825,2.4869); -v(40.5932,-10.4226,-5.87785); -v(39.4235,-10.1222,-3.68125); -v(40.7022,-9.96917e-15,-3.68125); -v(40.5932,-10.4226,-5.87785); -v(35.6676,-19.6085,-3.68125); -v(39.4235,-10.1222,-3.68125); -v(18.1588,-55.887,4.81754); -v(3.7477,-59.5681,2.4869); -v(18.4439,-56.7646,2.4869); -v(35.0825,-32.9446,-9.82287); -v(24.5099,-38.6214,-9.04827); -v(33.3446,-31.3127,-9.04827); -v(18.1588,-55.887,4.81754); -v(3.68976,-58.6471,4.81754); -v(3.7477,-59.5681,2.4869); -v(-10.3731,54.3777,-8.44328); -v(3.47597,55.249,-8.44328); -v(3.33356,52.9854,-9.51056); -v(35.0825,-32.9446,-9.82287); -v(25.7873,-40.6343,-9.82287); -v(24.5099,-38.6214,-9.04827); -v(-22.6047,48.0374,9.51056); -v(-9.94811,52.1498,9.51056); -v(-23.5704,50.0897,8.44328); -v(-10.3731,54.3777,-8.44328); -v(3.33356,52.9854,-9.51056); -v(-9.94811,52.1498,-9.51056); -v(-10.3731,54.3777,-8.44328); -v(3.59725,57.1766,-6.84547); -v(3.47597,55.249,-8.44328); -v(17.1066,-52.6488,-8.44328); -v(3.33356,-52.9854,-9.51056); -v(16.4058,-50.4918,-9.51056); -v(-9.94811,-52.1498,9.51056); -v(-22.6047,-48.0374,9.51056); -v(-10.3731,-54.3777,8.44328); -v(17.1066,-52.6488,-8.44328); -v(3.47597,-55.249,-8.44328); -v(3.33356,-52.9854,-9.51056); -v(2.87218,45.6519,9.04827); -v(14.1351,43.5034,9.04827); -v(3.02187,48.0312,9.82287); -v(17.1066,-52.6488,-8.44328); -v(3.59725,-57.1766,-6.84547); -v(3.47597,-55.249,-8.44328); -v(-11.184,-58.6286,-2.4869); -v(-11.2429,-58.9372,-2.44929e-15); -v(-25.5468,-54.2896,-2.44929e-15); -v(18.4439,56.7646,-2.4869); -v(18.541,57.0634,-2.44929e-15); -v(32.1496,50.6597,-2.44929e-15); -v(18.4439,56.7646,-2.4869); -v(3.76743,59.8816,-2.44929e-15); -v(18.541,57.0634,-2.44929e-15); -v(-11.184,-58.6286,-2.4869); -v(-25.5468,-54.2896,-2.44929e-15); -v(-25.413,-54.0054,-2.4869); -v(21.8093,34.366,3.68125); -v(29.6707,27.8626,3.68125); -v(30.551,28.6893,5.87785); -v(18.4439,56.7646,-2.4869); -v(31.9813,50.3944,-2.4869); -v(31.4868,49.6153,-4.81754); -v(-11.184,-58.6286,-2.4869); -v(-25.413,-54.0054,-2.4869); -v(-25.0201,-53.1704,-4.81754); -v(18.4439,56.7646,-2.4869); -v(31.4868,49.6153,-4.81754); -v(18.1588,55.887,-4.81754); -v(-11.184,-58.6286,-2.4869); -v(-25.0201,-53.1704,-4.81754); -v(-11.0111,-57.7222,-4.81754); -v(18.4439,56.7646,-2.4869); -v(32.1496,50.6597,-2.44929e-15); -v(31.9813,50.3944,-2.4869); -v(21.8093,34.366,3.68125); -v(29.2162,27.4359,1.25333); -v(29.6707,27.8626,3.68125); -v(40.0842,-22.0365,-9.04827); -v(33.3446,-31.3127,-9.04827); -v(38.2295,-21.0169,-7.70513); -v(21.8093,34.366,3.68125); -v(30.551,28.6893,5.87785); -v(22.4564,35.3856,5.87785); -v(-29.1572,-35.245,9.04827); -v(-37.0062,-26.8866,9.04827); -v(-30.6768,-37.0819,9.82287); -v(35.6676,19.6085,-3.68125); -v(38.8197,9.96721,-1.25333); -v(35.1214,19.3081,-1.25333); -v(28.4471,-44.8255,-9.51056); -v(16.4058,-50.4918,-9.51056); -v(27.1278,-42.7466,-9.98027); -v(35.6676,19.6085,-3.68125); -v(39.4235,10.1222,-3.68125); -v(38.8197,9.96721,-1.25333); -v(-37.844,-14.9835,3.68125); -v(-40.3813,-5.10134,3.68125); -v(-38.9668,-15.428,5.87785); -v(-55.4945,21.9718,2.4869); -v(-48.2869,35.0825,2.4869); -v(-55.7866,22.0875,-2.44929e-15); -v(-37.844,-14.9835,3.68125); -v(-39.7628,-5.02321,1.25333); -v(-40.3813,-5.10134,3.68125); -v(3.68976,-58.6471,-4.81754); -v(-11.0111,-57.7222,-4.81754); -v(3.59725,-57.1766,-6.84547); -v(-55.4945,21.9718,2.4869); -v(-55.7866,22.0875,-2.44929e-15); -v(-59.5269,7.51999,-2.44929e-15); -v(42.2552,-10.8493,-7.70513); -v(38.2295,-21.0169,-7.70513); -v(36.7259,-20.1902,-5.87785); -v(42.2552,-10.8493,-7.70513); -v(40.0842,-22.0365,-9.04827); -v(38.2295,-21.0169,-7.70513); -v(-35.2867,42.6543,8.44328); -v(-23.5704,50.0897,8.44328); -v(-24.3928,51.8373,6.84547); -v(42.2552,-10.8493,-7.70513); -v(41.9098,-1.02649e-14,-5.87785); -v(43.6258,-1.06852e-14,-7.70513); -v(42.2552,-10.8493,-7.70513); -v(43.6258,-1.06852e-14,-7.70513); -v(45.7422,-1.12036e-14,-9.04827); -v(-40.3813,5.10134,-3.68125); -v(-37.844,14.9835,-3.68125); -v(-39.7628,5.02321,-1.25333); -v(42.2552,-10.8493,-7.70513); -v(40.5932,-10.4226,-5.87785); -v(41.9098,-1.02649e-14,-5.87785); -v(42.2552,-10.8493,-7.70513); -v(36.7259,-20.1902,-5.87785); -v(40.5932,-10.4226,-5.87785); -v(-35.2867,42.6543,8.44328); -v(-22.6047,48.0374,9.51056); -v(-23.5704,50.0897,8.44328); -v(36.9062,-34.6572,-9.98027); -v(25.7873,-40.6343,-9.82287); -v(35.0825,-32.9446,-9.82287); -v(-35.2867,42.6543,8.44328); -v(-24.3928,51.8373,6.84547); -v(-36.5178,44.1425,6.84547); -v(-37.0062,26.8866,-9.04827); -v(-29.1572,35.245,-9.04827); -v(-35.294,25.6426,-7.70513); -v(36.9062,-34.6572,-9.98027); -v(28.4471,-44.8255,-9.51056); -v(27.1278,-42.7466,-9.98027); -v(36.9062,-34.6572,-9.98027); -v(27.1278,-42.7466,-9.98027); -v(25.7873,-40.6343,-9.82287); -v(17.7035,-54.4857,-6.84547); -v(3.68976,-58.6471,-4.81754); -v(3.59725,-57.1766,-6.84547); -v(-9.01795,47.2737,9.82287); -v(3.02187,48.0312,9.82287); -v(-9.48672,49.7311,9.98027); -v(17.7035,-54.4857,-6.84547); -v(3.59725,-57.1766,-6.84547); -v(17.1066,-52.6488,-8.44328); -v(-9.01795,47.2737,9.82287); -v(2.87218,45.6519,9.04827); -v(3.02187,48.0312,9.82287); -v(-22.6047,48.0374,-9.51056); -v(-9.94811,52.1498,-9.51056); -v(-21.5563,45.8095,-9.98027); -v(42.1733,-23.185,-9.82287); -v(33.3446,-31.3127,-9.04827); -v(40.0842,-22.0365,-9.04827); -v(42.1733,-23.185,-9.82287); -v(36.9062,-34.6572,-9.98027); -v(35.0825,-32.9446,-9.82287); -v(31.9813,-50.3944,2.4869); -v(18.4439,-56.7646,2.4869); -v(18.541,-57.0634,-2.44929e-15); -v(12.9508,39.8586,5.87785); -v(21.8093,34.366,3.68125); -v(22.4564,35.3856,5.87785); -v(42.1733,-23.185,-9.82287); -v(35.0825,-32.9446,-9.82287); -v(33.3446,-31.3127,-9.04827); -v(12.9508,39.8586,5.87785); -v(22.4564,35.3856,5.87785); -v(13.4811,41.4906,7.70513); -v(31.9813,-50.3944,2.4869); -v(18.541,-57.0634,-2.44929e-15); -v(32.1496,-50.6597,-2.44929e-15); -v(31.9813,-50.3944,2.4869); -v(32.1496,-50.6597,-2.44929e-15); -v(43.7381,-41.0728,-2.44929e-15); -v(29.6624,-46.7405,-8.44328); -v(16.4058,-50.4918,-9.51056); -v(28.4471,-44.8255,-9.51056); -v(29.6624,-46.7405,-8.44328); -v(17.1066,-52.6488,-8.44328); -v(16.4058,-50.4918,-9.51056); -v(29.2162,27.4359,-1.25333); -v(35.1214,19.3081,-1.25333); -v(29.2162,27.4359,1.25333); -v(3.47597,-55.249,8.44328); -v(-10.735,-56.2749,6.84547); -v(3.59725,-57.1766,6.84547); -v(29.6624,-46.7405,-8.44328); -v(17.7035,-54.4857,-6.84547); -v(17.1066,-52.6488,-8.44328); -v(29.2162,27.4359,-1.25333); -v(35.6676,19.6085,-3.68125); -v(35.1214,19.3081,-1.25333); -v(3.47597,-55.249,8.44328); -v(-9.94811,-52.1498,9.51056); -v(-10.3731,-54.3777,8.44328); -v(3.7477,-59.5681,-2.4869); -v(-11.184,-58.6286,-2.4869); -v(-11.0111,-57.7222,-4.81754); -v(3.47597,-55.249,8.44328); -v(-10.3731,-54.3777,8.44328); -v(-10.735,-56.2749,6.84547); -v(3.7477,-59.5681,-2.4869); -v(-11.0111,-57.7222,-4.81754); -v(3.68976,-58.6471,-4.81754); -v(3.7477,-59.5681,-2.4869); -v(3.76743,-59.8816,-2.44929e-15); -v(-11.2429,-58.9372,-2.44929e-15); -v(42.2552,10.8493,-7.70513); -v(41.9098,-1.02649e-14,-5.87785); -v(40.5932,10.4226,-5.87785); -v(3.68976,58.6471,-4.81754); -v(18.1588,55.887,-4.81754); -v(3.59725,57.1766,-6.84547); -v(3.7477,-59.5681,-2.4869); -v(-11.2429,-58.9372,-2.44929e-15); -v(-11.184,-58.6286,-2.4869); -v(42.2552,10.8493,-7.70513); -v(43.6258,-1.06852e-14,-7.70513); -v(41.9098,-1.02649e-14,-5.87785); -v(44.3051,-11.3756,-9.04827); -v(42.2552,-10.8493,-7.70513); -v(45.7422,-1.12036e-14,-9.04827); -v(42.2552,10.8493,-7.70513); -v(45.7422,-1.12036e-14,-9.04827); -v(43.6258,-1.06852e-14,-7.70513); -v(-20.4911,-43.5459,9.82287); -v(-30.6768,-37.0819,9.82287); -v(-21.5563,-45.8095,9.98027); -v(-20.4911,-43.5459,9.82287); -v(-29.1572,-35.245,9.04827); -v(-30.6768,-37.0819,9.82287); -v(44.3051,-11.3756,-9.04827); -v(40.0842,-22.0365,-9.04827); -v(42.2552,-10.8493,-7.70513); -v(38.7011,-36.3427,-9.51056); -v(28.4471,-44.8255,-9.51056); -v(36.9062,-34.6572,-9.98027); -v(-33.9058,-24.634,5.87785); -v(-37.844,-14.9835,3.68125); -v(-38.9668,-15.428,5.87785); -v(-46.3483,33.674,6.84547); -v(-37.457,45.2777,4.81754); -v(-47.5403,34.5401,4.81754); -v(18.1588,-55.887,-4.81754); -v(3.68976,-58.6471,-4.81754); -v(17.7035,-54.4857,-6.84547); -v(-46.3483,33.674,6.84547); -v(-36.5178,44.1425,6.84547); -v(-37.457,45.2777,4.81754); -v(-33.9058,-24.634,5.87785); -v(-38.9668,-15.428,5.87785); -v(-35.294,-25.6426,7.70513); -v(-21.5563,45.8095,9.98027); -v(-9.48672,49.7311,9.98027); -v(-9.94811,52.1498,9.51056); -v(44.3656,-24.3902,-9.98027); -v(38.7011,-36.3427,-9.51056); -v(36.9062,-34.6572,-9.98027); -v(-21.5563,45.8095,9.98027); -v(-9.94811,52.1498,9.51056); -v(-22.6047,48.0374,9.51056); -v(-21.5563,45.8095,9.98027); -v(-9.01795,47.2737,9.82287); -v(-9.48672,49.7311,9.98027); -v(-39.7628,-5.02321,-1.25333); -v(-39.7628,5.02321,-1.25333); -v(-39.7628,-5.02321,1.25333); -v(44.3656,-24.3902,-9.98027); -v(36.9062,-34.6572,-9.98027); -v(42.1733,-23.185,-9.82287); -v(-39.7628,-5.02321,-1.25333); -v(-40.3813,5.10134,-3.68125); -v(-39.7628,5.02321,-1.25333); -v(2.73928,43.5397,7.70513); -v(12.9508,39.8586,5.87785); -v(13.4811,41.4906,7.70513); -v(30.6973,-48.3713,-6.84547); -v(17.7035,-54.4857,-6.84547); -v(29.6624,-46.7405,-8.44328); -v(30.6973,-48.3713,-6.84547); -v(18.1588,-55.887,-4.81754); -v(17.7035,-54.4857,-6.84547); -v(2.73928,43.5397,7.70513); -v(14.1351,43.5034,9.04827); -v(2.87218,45.6519,9.04827); -v(-40.5622,16.0597,-7.70513); -v(-35.294,25.6426,-7.70513); -v(-38.9668,15.428,-5.87785); -v(46.6142,-11.9685,-9.82287); -v(40.0842,-22.0365,-9.04827); -v(44.3051,-11.3756,-9.04827); -v(2.73928,43.5397,7.70513); -v(13.4811,41.4906,7.70513); -v(14.1351,43.5034,9.04827); -v(46.6142,-11.9685,-9.82287); -v(44.3051,-11.3756,-9.04827); -v(45.7422,-1.12036e-14,-9.04827); -v(-40.5622,16.0597,-7.70513); -v(-37.0062,26.8866,-9.04827); -v(-35.294,25.6426,-7.70513); -v(46.6142,-11.9685,-9.82287); -v(45.7422,-1.12036e-14,-9.04827); -v(48.1262,-1.17875e-14,-9.82287); -v(46.6142,-11.9685,-9.82287); -v(42.1733,-23.185,-9.82287); -v(40.0842,-22.0365,-9.04827); -v(40.3544,-37.8953,-8.44328); -v(28.4471,-44.8255,-9.51056); -v(38.7011,-36.3427,-9.51056); -v(-32.2714,39.0095,-9.98027); -v(-21.5563,45.8095,-9.98027); -v(-30.6768,37.0819,-9.82287); -v(40.3544,-37.8953,-8.44328); -v(29.6624,-46.7405,-8.44328); -v(28.4471,-44.8255,-9.51056); -v(21.4753,33.8397,1.25333); -v(29.2162,27.4359,1.25333); -v(21.8093,34.366,3.68125); -v(-32.2714,39.0095,-9.98027); -v(-22.6047,48.0374,-9.51056); -v(-21.5563,45.8095,-9.98027); -v(36.7259,20.1902,-5.87785); -v(40.5932,10.4226,-5.87785); -v(39.4235,10.1222,-3.68125); -v(36.7259,20.1902,-5.87785); -v(39.4235,10.1222,-3.68125); -v(35.6676,19.6085,-3.68125); -v(17.7035,-54.4857,6.84547); -v(3.59725,-57.1766,6.84547); -v(3.68976,-58.6471,4.81754); -v(18.4439,-56.7646,-2.4869); -v(18.541,-57.0634,-2.44929e-15); -v(3.76743,-59.8816,-2.44929e-15); -v(17.7035,-54.4857,6.84547); -v(3.68976,-58.6471,4.81754); -v(18.1588,-55.887,4.81754); -v(18.4439,-56.7646,-2.4869); -v(3.76743,-59.8816,-2.44929e-15); -v(3.7477,-59.5681,-2.4869); -v(-10.735,56.2749,-6.84547); -v(3.68976,58.6471,-4.81754); -v(3.59725,57.1766,-6.84547); -v(18.4439,-56.7646,-2.4869); -v(3.7477,-59.5681,-2.4869); -v(3.68976,-58.6471,-4.81754); -v(-54.6365,21.6321,4.81754); -v(-47.5403,34.5401,4.81754); -v(-48.2869,35.0825,2.4869); -v(18.4439,-56.7646,-2.4869); -v(3.68976,-58.6471,-4.81754); -v(18.1588,-55.887,-4.81754); -v(-54.6365,21.6321,4.81754); -v(-48.2869,35.0825,2.4869); -v(-55.4945,21.9718,2.4869); -v(-10.735,56.2749,-6.84547); -v(3.59725,57.1766,-6.84547); -v(-10.3731,54.3777,-8.44328); -v(46.5233,-25.5764,-9.51056); -v(38.7011,-36.3427,-9.51056); -v(44.3656,-24.3902,-9.98027); -v(-9.48672,-49.7311,9.98027); -v(-22.6047,-48.0374,9.51056); -v(-9.94811,-52.1498,9.51056); -v(31.4868,-49.6153,-4.81754); -v(18.1588,-55.887,-4.81754); -v(30.6973,-48.3713,-6.84547); -v(-9.48672,-49.7311,9.98027); -v(-21.5563,-45.8095,9.98027); -v(-22.6047,-48.0374,9.51056); -v(49.0373,-12.5906,-9.98027); -v(42.1733,-23.185,-9.82287); -v(46.6142,-11.9685,-9.82287); -v(-33.8409,40.9067,9.51056); -v(-22.6047,48.0374,9.51056); -v(-35.2867,42.6543,8.44328); -v(-9.48672,-49.7311,9.98027); -v(-20.4911,-43.5459,9.82287); -v(-21.5563,-45.8095,9.98027); -v(49.0373,-12.5906,-9.98027); -v(44.3656,-24.3902,-9.98027); -v(42.1733,-23.185,-9.82287); -v(49.0373,-12.5906,-9.98027); -v(48.1262,-1.17875e-14,-9.82287); -v(50.6279,-1.24003e-14,-9.98027); -v(49.0373,-12.5906,-9.98027); -v(50.6279,-1.24003e-14,-9.98027); -v(53.0902,-1.30033e-14,-9.51056); -v(49.0373,-12.5906,-9.98027); -v(46.5233,-25.5764,-9.51056); -v(44.3656,-24.3902,-9.98027); -v(49.0373,-12.5906,-9.98027); -v(46.6142,-11.9685,-9.82287); -v(48.1262,-1.17875e-14,-9.82287); -v(-27.8081,-33.6142,7.70513); -v(-35.294,-25.6426,7.70513); -v(-37.0062,-26.8866,9.04827); -v(41.7624,-39.2175,-6.84547); -v(29.6624,-46.7405,-8.44328); -v(40.3544,-37.8953,-8.44328); -v(-8.57123,44.932,9.04827); -v(2.87218,45.6519,9.04827); -v(-9.01795,47.2737,9.82287); -v(-27.8081,-33.6142,7.70513); -v(-37.0062,-26.8866,9.04827); -v(-29.1572,-35.245,9.04827); -v(-27.8081,-33.6142,7.70513); -v(-33.9058,-24.634,5.87785); -v(-35.294,-25.6426,7.70513); -v(41.7624,-39.2175,-6.84547); -v(31.4868,-49.6153,-4.81754); -v(30.6973,-48.3713,-6.84547); -v(-37.2644,-14.754,1.25333); -v(-39.7628,-5.02321,-1.25333); -v(-39.7628,-5.02321,1.25333); -v(41.7624,-39.2175,-6.84547); -v(30.6973,-48.3713,-6.84547); -v(29.6624,-46.7405,-8.44328); -v(48.5108,-26.669,-8.44328); -v(40.3544,-37.8953,-8.44328); -v(38.7011,-36.3427,-9.51056); -v(12.5777,38.7101,3.68125); -v(21.8093,34.366,3.68125); -v(12.9508,39.8586,5.87785); -v(-37.2644,-14.754,1.25333); -v(-39.7628,-5.02321,1.25333); -v(-37.844,-14.9835,3.68125); -v(48.5108,-26.669,-8.44328); -v(41.7624,-39.2175,-6.84547); -v(40.3544,-37.8953,-8.44328); -v(12.5777,38.7101,3.68125); -v(21.4753,33.8397,1.25333); -v(21.8093,34.366,3.68125); -v(48.5108,-26.669,-8.44328); -v(38.7011,-36.3427,-9.51056); -v(46.5233,-25.5764,-9.51056); -v(-41.5794,5.25269,-5.87785); -v(-40.5622,16.0597,-7.70513); -v(-38.9668,15.428,-5.87785); -v(-41.5794,5.25269,-5.87785); -v(-38.9668,15.428,-5.87785); -v(-37.844,14.9835,-3.68125); -v(31.9813,-50.3944,-2.4869); -v(18.1588,-55.887,-4.81754); -v(31.4868,-49.6153,-4.81754); -v(31.9813,-50.3944,-2.4869); -v(32.1496,-50.6597,-2.44929e-15); -v(18.541,-57.0634,-2.44929e-15); -v(31.9813,-50.3944,-2.4869); -v(43.7381,-41.0728,-2.44929e-15); -v(32.1496,-50.6597,-2.44929e-15); -v(29.6707,27.8626,-3.68125); -v(35.6676,19.6085,-3.68125); -v(29.2162,27.4359,-1.25333); -v(-41.5794,5.25269,-5.87785); -v(-37.844,14.9835,-3.68125); -v(-40.3813,5.10134,-3.68125); -v(31.9813,-50.3944,-2.4869); -v(18.4439,-56.7646,-2.4869); -v(18.1588,-55.887,-4.81754); -v(31.9813,-50.3944,-2.4869); -v(18.541,-57.0634,-2.44929e-15); -v(18.4439,-56.7646,-2.4869); -v(51.4222,-13.203,-9.51056); -v(49.0373,-12.5906,-9.98027); -v(53.0902,-1.30033e-14,-9.51056); -v(-38.9349,28.2879,-9.82287); -v(-32.2714,39.0095,-9.98027); -v(-30.6768,37.0819,-9.82287); -v(51.4222,-13.203,-9.51056); -v(46.5233,-25.5764,-9.51056); -v(49.0373,-12.5906,-9.98027); -v(44.3051,11.3756,-9.04827); -v(45.7422,-1.12036e-14,-9.04827); -v(42.2552,10.8493,-7.70513); -v(-38.9349,28.2879,-9.82287); -v(-30.6768,37.0819,-9.82287); -v(-29.1572,35.245,-9.04827); -v(-38.9349,28.2879,-9.82287); -v(-29.1572,35.245,-9.04827); -v(-37.0062,26.8866,-9.04827); -v(42.8364,-40.2261,-4.81754); -v(31.4868,-49.6153,-4.81754); -v(41.7624,-39.2175,-6.84547); -v(-59.2152,7.48062,2.4869); -v(-55.4945,21.9718,2.4869); -v(-59.5269,7.51999,-2.44929e-15); -v(31.4868,-49.6153,4.81754); -v(18.1588,-55.887,4.81754); -v(18.4439,-56.7646,2.4869); -v(31.4868,-49.6153,4.81754); -v(18.4439,-56.7646,2.4869); -v(31.9813,-50.3944,2.4869); -v(50.2033,-27.5995,-6.84547); -v(41.7624,-39.2175,-6.84547); -v(48.5108,-26.669,-8.44328); -v(50.2033,-27.5995,-6.84547); -v(42.8364,-40.2261,-4.81754); -v(41.7624,-39.2175,-6.84547); -v(-44.7858,32.5388,8.44328); -v(-33.8409,40.9067,9.51056); -v(-35.2867,42.6543,8.44328); -v(53.6191,-13.767,-8.44328); -v(53.0902,-1.30033e-14,-9.51056); -v(55.3583,-1.35589e-14,-8.44328); -v(-23.5704,50.0897,-8.44328); -v(-10.735,56.2749,-6.84547); -v(-10.3731,54.3777,-8.44328); -v(-44.7858,32.5388,8.44328); -v(-36.5178,44.1425,6.84547); -v(-46.3483,33.674,6.84547); -v(-23.5704,50.0897,-8.44328); -v(-10.3731,54.3777,-8.44328); -v(-9.94811,52.1498,-9.51056); -v(53.6191,-13.767,-8.44328); -v(48.5108,-26.669,-8.44328); -v(46.5233,-25.5764,-9.51056); -v(-23.5704,50.0897,-8.44328); -v(-9.94811,52.1498,-9.51056); -v(-22.6047,48.0374,-9.51056); -v(53.6191,-13.767,-8.44328); -v(51.4222,-13.203,-9.51056); -v(53.0902,-1.30033e-14,-9.51056); -v(-44.7858,32.5388,8.44328); -v(-35.2867,42.6543,8.44328); -v(-36.5178,44.1425,6.84547); -v(53.6191,-13.767,-8.44328); -v(46.5233,-25.5764,-9.51056); -v(51.4222,-13.203,-9.51056); -v(3.33356,-52.9854,9.51056); -v(-9.94811,-52.1498,9.51056); -v(3.47597,-55.249,8.44328); -v(43.5091,-40.8578,-2.4869); -v(31.9813,-50.3944,-2.4869); -v(31.4868,-49.6153,-4.81754); -v(43.5091,-40.8578,-2.4869); -v(43.7381,-41.0728,-2.44929e-15); -v(31.9813,-50.3944,-2.4869); -v(43.5091,-40.8578,-2.4869); -v(31.4868,-49.6153,-4.81754); -v(42.8364,-40.2261,-4.81754); -v(-20.4911,43.5459,9.82287); -v(-9.01795,47.2737,9.82287); -v(-21.5563,45.8095,9.98027); -v(3.7477,59.5681,-2.4869); -v(18.1588,55.887,-4.81754); -v(3.68976,58.6471,-4.81754); -v(-20.4911,43.5459,9.82287); -v(-8.57123,44.932,9.04827); -v(-9.01795,47.2737,9.82287); -v(3.7477,59.5681,-2.4869); -v(3.76743,59.8816,-2.44929e-15); -v(18.4439,56.7646,-2.4869); -v(3.7477,59.5681,-2.4869); -v(18.4439,56.7646,-2.4869); -v(18.1588,55.887,-4.81754); -v(51.4945,-28.3093,-4.81754); -v(42.8364,-40.2261,-4.81754); -v(50.2033,-27.5995,-6.84547); -v(55.4898,-14.2474,-6.84547); -v(55.3583,-1.35589e-14,-8.44328); -v(57.2897,-1.40319e-14,-6.84547); -v(55.4898,-14.2474,-6.84547); -v(57.2897,-1.40319e-14,-6.84547); -v(58.7631,-1.43928e-14,-4.81754); -v(55.4898,-14.2474,-6.84547); -v(51.4945,-28.3093,-4.81754); -v(50.2033,-27.5995,-6.84547); -v(2.63154,41.8271,5.87785); -v(12.9508,39.8586,5.87785); -v(2.73928,43.5397,7.70513); -v(55.4898,-14.2474,-6.84547); -v(53.6191,-13.767,-8.44328); -v(55.3583,-1.35589e-14,-8.44328); -v(2.63154,41.8271,5.87785); -v(12.5777,38.7101,3.68125); -v(12.9508,39.8586,5.87785); -v(55.4898,-14.2474,-6.84547); -v(50.2033,-27.5995,-6.84547); -v(48.5108,-26.669,-8.44328); -v(21.4753,33.8397,-1.25333); -v(29.2162,27.4359,-1.25333); -v(29.2162,27.4359,1.25333); -v(-19.4761,-41.3888,9.04827); -v(-29.1572,-35.245,9.04827); -v(-20.4911,-43.5459,9.82287); -v(55.4898,-14.2474,-6.84547); -v(48.5108,-26.669,-8.44328); -v(53.6191,-13.767,-8.44328); -v(52.3031,-28.7539,-2.4869); -v(52.5784,-28.9052,-2.44929e-15); -v(43.7381,-41.0728,-2.44929e-15); -v(52.3031,-28.7539,-2.4869); -v(43.7381,-41.0728,-2.44929e-15); -v(43.5091,-40.8578,-2.4869); -v(52.3031,-28.7539,-2.4869); -v(58.115,-14.9214,-2.44929e-15); -v(52.5784,-28.9052,-2.44929e-15); -v(21.4753,33.8397,-1.25333); -v(29.2162,27.4359,1.25333); -v(21.4753,33.8397,1.25333); -v(52.3031,-28.7539,-2.4869); -v(43.5091,-40.8578,-2.4869); -v(42.8364,-40.2261,-4.81754); -v(-32.9288,-23.9242,3.68125); -v(-37.2644,-14.754,1.25333); -v(-37.844,-14.9835,3.68125); -v(52.3031,-28.7539,-2.4869); -v(42.8364,-40.2261,-4.81754); -v(51.4945,-28.3093,-4.81754); -v(56.9169,-14.6138,-4.81754); -v(55.4898,-14.2474,-6.84547); -v(58.7631,-1.43928e-14,-4.81754); -v(56.9169,-14.6138,-4.81754); -v(51.4945,-28.3093,-4.81754); -v(55.4898,-14.2474,-6.84547); -v(-32.9288,-23.9242,3.68125); -v(-37.844,-14.9835,3.68125); -v(-33.9058,-24.634,5.87785); -v(38.2295,21.0169,-7.70513); -v(44.3051,11.3756,-9.04827); -v(42.2552,10.8493,-7.70513); -v(57.8107,-14.8433,-2.4869); -v(51.4945,-28.3093,-4.81754); -v(56.9169,-14.6138,-4.81754); -v(57.8107,-14.8433,-2.4869); -v(60,-1.46958e-14,-2.44929e-15); -v(58.115,-14.9214,-2.44929e-15); -v(57.8107,-14.8433,-2.4869); -v(58.7631,-1.43928e-14,-4.81754); -v(59.6858,-1.46188e-14,-2.4869); -v(38.2295,21.0169,-7.70513); -v(40.5932,10.4226,-5.87785); -v(36.7259,20.1902,-5.87785); -v(-40.3813,-5.10134,-3.68125); -v(-40.3813,5.10134,-3.68125); -v(-39.7628,-5.02321,-1.25333); -v(57.8107,-14.8433,-2.4869); -v(59.6858,-1.46188e-14,-2.4869); -v(60,-1.46958e-14,-2.44929e-15); -v(38.2295,21.0169,-7.70513); -v(42.2552,10.8493,-7.70513); -v(40.5932,10.4226,-5.87785); -v(57.8107,-14.8433,-2.4869); -v(56.9169,-14.6138,-4.81754); -v(58.7631,-1.43928e-14,-4.81754); -v(57.8107,-14.8433,-2.4869); -v(58.115,-14.9214,-2.44929e-15); -v(52.3031,-28.7539,-2.4869); -v(57.8107,-14.8433,-2.4869); -v(52.3031,-28.7539,-2.4869); -v(51.4945,-28.3093,-4.81754); -v(-53.2666,21.0897,6.84547); -v(-46.3483,33.674,6.84547); -v(-47.5403,34.5401,4.81754); -v(-42.53,16.8388,-9.04827); -v(-37.0062,26.8866,-9.04827); -v(-40.5622,16.0597,-7.70513); -v(-53.2666,21.0897,6.84547); -v(-47.5403,34.5401,4.81754); -v(-54.6365,21.6321,4.81754); -v(-32.2714,39.0095,9.98027); -v(-20.4911,43.5459,9.82287); -v(-21.5563,45.8095,9.98027); -v(-33.8409,40.9067,-9.51056); -v(-22.6047,48.0374,-9.51056); -v(-32.2714,39.0095,-9.98027); -v(-32.2714,39.0095,9.98027); -v(-21.5563,45.8095,9.98027); -v(-22.6047,48.0374,9.51056); -v(-32.2714,39.0095,9.98027); -v(-22.6047,48.0374,9.51056); -v(-33.8409,40.9067,9.51056); -v(43.5091,-40.8578,2.4869); -v(31.9813,-50.3944,2.4869); -v(43.7381,-41.0728,-2.44929e-15); -v(-8.17465,42.853,7.70513); -v(2.63154,41.8271,5.87785); -v(2.73928,43.5397,7.70513); -v(17.1066,-52.6488,8.44328); -v(3.33356,-52.9854,9.51056); -v(3.47597,-55.249,8.44328); -v(17.1066,-52.6488,8.44328); -v(3.47597,-55.249,8.44328); -v(3.59725,-57.1766,6.84547); -v(-8.17465,42.853,7.70513); -v(2.73928,43.5397,7.70513); -v(2.87218,45.6519,9.04827); -v(-8.17465,42.853,7.70513); -v(2.87218,45.6519,9.04827); -v(-8.57123,44.932,9.04827); -v(17.1066,-52.6488,8.44328); -v(3.59725,-57.1766,6.84547); -v(17.7035,-54.4857,6.84547); -v(-11.0111,57.7222,-4.81754); -v(3.68976,58.6471,-4.81754); -v(-10.735,56.2749,-6.84547); -v(12.385,38.1173,1.25333); -v(21.4753,33.8397,-1.25333); -v(21.4753,33.8397,1.25333); -v(-9.01795,-47.2737,9.82287); -v(-19.4761,-41.3888,9.04827); -v(-20.4911,-43.5459,9.82287); -v(12.385,38.1173,1.25333); -v(21.4753,33.8397,1.25333); -v(12.5777,38.7101,3.68125); -v(-9.01795,-47.2737,9.82287); -v(-20.4911,-43.5459,9.82287); -v(-9.48672,-49.7311,9.98027); -v(30.551,28.6893,-5.87785); -v(38.2295,21.0169,-7.70513); -v(36.7259,20.1902,-5.87785); -v(30.551,28.6893,-5.87785); -v(36.7259,20.1902,-5.87785); -v(35.6676,19.6085,-3.68125); -v(30.551,28.6893,-5.87785); -v(35.6676,19.6085,-3.68125); -v(29.6707,27.8626,-3.68125); -v(-26.7143,-32.2921,5.87785); -v(-32.9288,-23.9242,3.68125); -v(-33.9058,-24.634,5.87785); -v(46.6142,11.9685,-9.82287); -v(45.7422,-1.12036e-14,-9.04827); -v(44.3051,11.3756,-9.04827); -v(-26.7143,-32.2921,5.87785); -v(-33.9058,-24.634,5.87785); -v(-27.8081,-33.6142,7.70513); -v(46.6142,11.9685,-9.82287); -v(48.1262,-1.17875e-14,-9.82287); -v(45.7422,-1.12036e-14,-9.04827); -v(-58.2997,7.36496,4.81754); -v(-54.6365,21.6321,4.81754); -v(-55.4945,21.9718,2.4869); -v(-37.2644,-14.754,-1.25333); -v(-39.7628,-5.02321,-1.25333); -v(-37.2644,-14.754,1.25333); -v(-37.2644,-14.754,-1.25333); -v(-40.3813,-5.10134,-3.68125); -v(-39.7628,-5.02321,-1.25333); -v(-58.2997,7.36496,4.81754); -v(-55.4945,21.9718,2.4869); -v(-59.2152,7.48062,2.4869); -v(-43.2818,5.46776,-7.70513); -v(-42.53,16.8388,-9.04827); -v(-40.5622,16.0597,-7.70513); -v(-42.9509,31.2056,9.51056); -v(-33.8409,40.9067,9.51056); -v(-44.7858,32.5388,8.44328); -v(-43.2818,5.46776,-7.70513); -v(-40.5622,16.0597,-7.70513); -v(-41.5794,5.25269,-5.87785); -v(-40.9588,29.7583,-9.98027); -v(-32.2714,39.0095,-9.98027); -v(-38.9349,28.2879,-9.82287); -v(-40.9588,29.7583,-9.98027); -v(-33.8409,40.9067,-9.51056); -v(-32.2714,39.0095,-9.98027); -v(-19.4761,41.3888,9.04827); -v(-8.57123,44.932,9.04827); -v(-20.4911,43.5459,9.82287); -v(-24.3928,51.8373,-6.84547); -v(-10.735,56.2749,-6.84547); -v(-23.5704,50.0897,-8.44328); -v(-24.3928,51.8373,-6.84547); -v(-11.0111,57.7222,-4.81754); -v(-10.735,56.2749,-6.84547); -v(30.6973,-48.3713,6.84547); -v(17.7035,-54.4857,6.84547); -v(18.1588,-55.887,4.81754); -v(2.55571,40.6219,3.68125); -v(12.5777,38.7101,3.68125); -v(2.63154,41.8271,5.87785); -v(2.55571,40.6219,3.68125); -v(12.385,38.1173,1.25333); -v(12.5777,38.7101,3.68125); -v(30.6973,-48.3713,6.84547); -v(18.1588,-55.887,4.81754); -v(31.4868,-49.6153,4.81754); -v(3.17895,-50.528,9.98027); -v(-9.94811,-52.1498,9.51056); -v(3.33356,-52.9854,9.51056); -v(3.17895,-50.528,9.98027); -v(-9.48672,-49.7311,9.98027); -v(-9.94811,-52.1498,9.51056); -v(3.17895,-50.528,9.98027); -v(-9.01795,-47.2737,9.82287); -v(-9.48672,-49.7311,9.98027); -v(21.8093,34.366,-3.68125); -v(29.6707,27.8626,-3.68125); -v(29.2162,27.4359,-1.25333); -v(-18.5749,-39.4738,7.70513); -v(-27.8081,-33.6142,7.70513); -v(-29.1572,-35.245,9.04827); -v(21.8093,34.366,-3.68125); -v(29.2162,27.4359,-1.25333); -v(21.4753,33.8397,-1.25333); -v(-18.5749,-39.4738,7.70513); -v(-29.1572,-35.245,9.04827); -v(-19.4761,-41.3888,9.04827); -v(-18.5749,-39.4738,7.70513); -v(-26.7143,-32.2921,5.87785); -v(-27.8081,-33.6142,7.70513); -v(40.0842,22.0365,-9.04827); -v(44.3051,11.3756,-9.04827); -v(38.2295,21.0169,-7.70513); -v(-32.4245,-23.5578,1.25333); -v(-37.2644,-14.754,-1.25333); -v(-37.2644,-14.754,1.25333); -v(-59.2152,-7.48062,2.4869); -v(-59.2152,7.48062,2.4869); -v(-59.5269,7.51999,-2.44929e-15); -v(-59.2152,-7.48062,2.4869); -v(-59.5269,7.51999,-2.44929e-15); -v(-59.5269,-7.51999,-2.44929e-15); -v(-32.4245,-23.5578,1.25333); -v(-37.2644,-14.754,1.25333); -v(-32.9288,-23.9242,3.68125); -v(-51.4708,20.3787,8.44328); -v(-46.3483,33.674,6.84547); -v(-53.2666,21.0897,6.84547); -v(-41.5794,-5.25269,-5.87785); -v(-41.5794,5.25269,-5.87785); -v(-40.3813,5.10134,-3.68125); -v(-41.5794,-5.25269,-5.87785); -v(-40.3813,5.10134,-3.68125); -v(-40.3813,-5.10134,-3.68125); -v(-51.4708,20.3787,8.44328); -v(-42.9509,31.2056,9.51056); -v(-44.7858,32.5388,8.44328); -v(-51.4708,20.3787,8.44328); -v(-44.7858,32.5388,8.44328); -v(-46.3483,33.674,6.84547); -v(-41.5794,-5.25269,-5.87785); -v(-43.2818,5.46776,-7.70513); -v(-41.5794,5.25269,-5.87785); -v(-44.7466,17.7164,-9.82287); -v(-38.9349,28.2879,-9.82287); -v(-37.0062,26.8866,-9.04827); -v(-30.6768,37.0819,9.82287); -v(-19.4761,41.3888,9.04827); -v(-20.4911,43.5459,9.82287); -v(-44.7466,17.7164,-9.82287); -v(-37.0062,26.8866,-9.04827); -v(-42.53,16.8388,-9.04827); -v(-44.7466,17.7164,-9.82287); -v(-40.9588,29.7583,-9.98027); -v(-38.9349,28.2879,-9.82287); -v(-35.2867,42.6543,-8.44328); -v(-22.6047,48.0374,-9.51056); -v(-33.8409,40.9067,-9.51056); -v(-30.6768,37.0819,9.82287); -v(-20.4911,43.5459,9.82287); -v(-32.2714,39.0095,9.98027); -v(-35.2867,42.6543,-8.44328); -v(-23.5704,50.0897,-8.44328); -v(-22.6047,48.0374,-9.51056); -v(-35.2867,42.6543,-8.44328); -v(-24.3928,51.8373,-6.84547); -v(-23.5704,50.0897,-8.44328); -v(-7.85312,41.1675,5.87785); -v(2.55571,40.6219,3.68125); -v(2.63154,41.8271,5.87785); -v(-7.85312,41.1675,5.87785); -v(2.63154,41.8271,5.87785); -v(-8.17465,42.853,7.70513); -v(42.8364,-40.2261,4.81754); -v(31.4868,-49.6153,4.81754); -v(31.9813,-50.3944,2.4869); -v(42.8364,-40.2261,4.81754); -v(31.9813,-50.3944,2.4869); -v(43.5091,-40.8578,2.4869); -v(12.385,38.1173,-1.25333); -v(21.8093,34.366,-3.68125); -v(21.4753,33.8397,-1.25333); -v(12.385,38.1173,-1.25333); -v(21.4753,33.8397,-1.25333); -v(12.385,38.1173,1.25333); -v(16.4058,-50.4918,9.51056); -v(3.33356,-52.9854,9.51056); -v(17.1066,-52.6488,8.44328); -v(-11.184,58.6286,-2.4869); -v(-11.2429,58.9372,-2.44929e-15); -v(3.76743,59.8816,-2.44929e-15); -v(31.8018,29.8639,-7.70513); -v(40.0842,22.0365,-9.04827); -v(38.2295,21.0169,-7.70513); -v(-11.184,58.6286,-2.4869); -v(3.7477,59.5681,-2.4869); -v(3.68976,58.6471,-4.81754); -v(-11.184,58.6286,-2.4869); -v(3.76743,59.8816,-2.44929e-15); -v(3.7477,59.5681,-2.4869); -v(31.8018,29.8639,-7.70513); -v(38.2295,21.0169,-7.70513); -v(30.551,28.6893,-5.87785); -v(-11.184,58.6286,-2.4869); -v(3.68976,58.6471,-4.81754); -v(-11.0111,57.7222,-4.81754); -v(49.0373,12.5906,-9.98027); -v(48.1262,-1.17875e-14,-9.82287); -v(46.6142,11.9685,-9.82287); -v(-8.57123,-44.932,9.04827); -v(-19.4761,-41.3888,9.04827); -v(-9.01795,-47.2737,9.82287); -v(49.0373,12.5906,-9.98027); -v(50.6279,-1.24003e-14,-9.98027); -v(48.1262,-1.17875e-14,-9.82287); -v(49.0373,12.5906,-9.98027); -v(53.0902,-1.30033e-14,-9.51056); -v(50.6279,-1.24003e-14,-9.98027); -v(-56.8379,7.1803,6.84547); -v(-53.2666,21.0897,6.84547); -v(-54.6365,21.6321,4.81754); -v(-25.9446,-31.3616,3.68125); -v(-32.4245,-23.5578,1.25333); -v(-32.9288,-23.9242,3.68125); -v(-56.8379,7.1803,6.84547); -v(-54.6365,21.6321,4.81754); -v(-58.2997,7.36496,4.81754); -v(-25.9446,-31.3616,3.68125); -v(-32.9288,-23.9242,3.68125); -v(-26.7143,-32.2921,5.87785); -v(-40.9588,29.7583,9.98027); -v(-32.2714,39.0095,9.98027); -v(-33.8409,40.9067,9.51056); -v(-40.9588,29.7583,9.98027); -v(-33.8409,40.9067,9.51056); -v(-42.9509,31.2056,9.51056); -v(-37.844,-14.9835,-3.68125); -v(-40.3813,-5.10134,-3.68125); -v(-37.2644,-14.754,-1.25333); -v(-40.9588,29.7583,9.98027); -v(-30.6768,37.0819,9.82287); -v(-32.2714,39.0095,9.98027); -v(-45.3815,5.73302,-9.04827); -v(-42.53,16.8388,-9.04827); -v(-43.2818,5.46776,-7.70513); -v(-18.5749,39.4738,7.70513); -v(-8.57123,44.932,9.04827); -v(-19.4761,41.3888,9.04827); -v(-18.5749,39.4738,7.70513); -v(-8.17465,42.853,7.70513); -v(-8.57123,44.932,9.04827); -v(-18.5749,39.4738,7.70513); -v(-7.85312,41.1675,5.87785); -v(-8.17465,42.853,7.70513); -v(-42.9509,31.2056,-9.51056); -v(-33.8409,40.9067,-9.51056); -v(-40.9588,29.7583,-9.98027); -v(2.51657,39.9998,1.25333); -v(12.385,38.1173,1.25333); -v(2.55571,40.6219,3.68125); -v(52.3031,-28.7539,2.4869); -v(43.5091,-40.8578,2.4869); -v(43.7381,-41.0728,-2.44929e-15); -v(2.51657,39.9998,1.25333); -v(12.385,38.1173,-1.25333); -v(12.385,38.1173,1.25333); -v(52.3031,-28.7539,2.4869); -v(43.7381,-41.0728,-2.44929e-15); -v(52.5784,-28.9052,-2.44929e-15); -v(52.3031,-28.7539,2.4869); -v(52.5784,-28.9052,-2.44929e-15); -v(58.115,-14.9214,-2.44929e-15); -v(22.4564,35.3856,-5.87785); -v(30.551,28.6893,-5.87785); -v(29.6707,27.8626,-3.68125); -v(29.6624,-46.7405,8.44328); -v(16.4058,-50.4918,9.51056); -v(17.1066,-52.6488,8.44328); -v(22.4564,35.3856,-5.87785); -v(29.6707,27.8626,-3.68125); -v(21.8093,34.366,-3.68125); -v(29.6624,-46.7405,8.44328); -v(17.7035,-54.4857,6.84547); -v(30.6973,-48.3713,6.84547); -v(29.6624,-46.7405,8.44328); -v(17.1066,-52.6488,8.44328); -v(17.7035,-54.4857,6.84547); -f3(0,1,2,-0.164203,-0.0902716,-0.982287,-0.412403,-0.105887,-0.904827,-0.373113,-0.205121,-0.904827); -f3(3,4,5,-0.373113,0.792906,-0.481754,-0.164203,0.860785,-0.481754,-0.31038,0.659591,-0.684547); -f3(6,7,8,-0.164203,-0.0902716,-0.982287,-0.181494,-0.0465998,-0.982287,-0.412403,-0.105887,-0.904827); -f3(9,10,11,-0.869397,-0.10983,0.481754,-0.960946,0.121396,0.24869,-0.960946,-0.121396,0.24869); -f3(12,13,14,-0.869397,-0.10983,0.481754,-0.869397,0.10983,0.481754,-0.960946,0.121396,0.24869); -f3(15,16,17,-0.0117658,0.187012,0.982287,0.0351118,0.184062,0.982287,0.00394265,-0.0626666,0.998027); -f3(18,19,20,-0.0117658,0.187012,0.982287,0.0797831,0.418238,0.904827,0.0351118,0.184062,0.982287); -f3(21,22,23,0.344463,0.73202,0.587785,0.515687,0.623358,0.587785,0.271402,0.576758,0.770513); -f3(24,25,26,0.344463,0.73202,0.587785,0.592662,0.716405,0.368125,0.515687,0.623358,0.587785); -f3(27,28,29,-0.287317,0.113757,0.951057,-0.25,0.181636,0.951057,-0.498199,0.197251,0.844328); -f3(30,31,32,0.802638,0.58315,-0.125333,0.864484,0.342274,-0.368125,0.922445,0.365222,-0.125333); -f3(33,34,35,0.802638,0.58315,-0.125333,0.922445,0.365222,-0.125333,0.802638,0.58315,0.125333); -f3(36,37,38,0.271402,-0.328069,0.904827,0.181288,-0.385257,0.904827,0.119441,-0.14438,0.982287); -f3(39,40,41,0.632398,0.0798904,-0.770513,0.632398,-0.0798904,-0.770513,0.802638,0.101397,-0.587785); -f3(42,43,44,0.632398,0.0798904,-0.770513,0.422422,-0.0533643,-0.904827,0.632398,-0.0798904,-0.770513); -f3(45,46,47,0.174223,-0.913308,0.368125,-0.0622954,-0.990157,0.125333,-0.0583811,-0.927942,0.368125); -f3(48,49,50,0.174223,-0.913308,0.368125,-0.0583811,-0.927942,0.368125,0.151595,-0.794687,0.587785); -f3(51,52,53,-0.0583811,0.0231147,-0.998027,-0.0507986,0.0369073,-0.998027,0.174223,-0.0689797,-0.982287); -f3(54,55,56,-0.0583811,0.0231147,-0.998027,-0.25,0.181636,-0.951057,-0.0507986,0.0369073,-0.998027); -f3(57,58,59,-0.287317,-0.88427,-0.368125,-0.498199,-0.785036,-0.368125,-0.30658,-0.943557,-0.125333); -f3(60,61,62,-0.464662,0.56168,-0.684547,-0.31038,0.659591,-0.684547,-0.341549,0.412862,-0.844328); -f3(63,64,65,-0.464662,0.56168,-0.684547,-0.373113,0.792906,-0.481754,-0.31038,0.659591,-0.684547); -f3(66,67,68,0.531395,-0.499013,0.684547,0.390601,-0.615489,0.684547,0.469549,-0.73989,0.481754); -f3(69,70,71,-0.31038,-0.291466,-0.904827,-0.373113,-0.205121,-0.904827,-0.464662,-0.436347,-0.770513); -f3(72,73,74,0.531395,-0.499013,0.684547,0.469549,-0.73989,0.481754,0.6388,-0.599873,0.481754); -f3(75,76,77,-0.900566,-0.356559,0.24869,-0.960946,-0.121396,0.24869,-0.992115,-0.125333,0); -f3(78,79,80,-0.900566,-0.356559,0.24869,-0.992115,-0.125333,0,-0.929776,-0.368125,0); -f3(81,82,83,0.0194033,-0.0597173,0.998027,0.0194033,-0.308407,0.951057,0.0954915,-0.293893,0.951057); -f3(84,85,86,-0.900566,-0.356559,0.24869,-0.929776,-0.368125,0,-0.809017,-0.587785,0); -f3(87,88,89,0.0194033,-0.0597173,0.998027,-0.0117658,0.187012,0.982287,0.00394265,-0.0626666,0.998027); -f3(90,91,92,0.0194033,-0.0597173,0.998027,0.00394265,-0.0626666,0.998027,0.0194033,-0.308407,0.951057); -f3(93,94,95,0.299309,0.0768494,-0.951057,0.309017,0,-0.951057,0.0608178,0.0156154,-0.998027); -f3(96,97,98,0.119441,0.626133,0.770513,0.344463,0.73202,0.587785,0.271402,0.576758,0.770513); -f3(99,100,101,-0.531602,0.0671569,0.844328,-0.498199,0.197251,0.844328,-0.677778,0.268351,0.684547); -f3(102,103,104,0.119441,0.626133,0.770513,0.181288,0.385257,0.904827,0.0797831,0.418238,0.904827); -f3(105,106,107,0.119441,0.626133,0.770513,0.271402,0.576758,0.770513,0.181288,0.385257,0.904827); -f3(108,109,110,-0.531602,0.0671569,0.844328,-0.287317,0.113757,0.951057,-0.498199,0.197251,0.844328); -f3(111,112,113,0.632398,0.764437,0.125333,0.802638,0.58315,0.125333,0.592662,0.716405,0.368125); -f3(114,115,116,-0.531602,0.0671569,0.844328,-0.677778,0.268351,0.684547,-0.72322,0.091364,0.684547); -f3(117,118,119,0.632398,0.764437,0.125333,0.802638,0.58315,-0.125333,0.802638,0.58315,0.125333); -f3(120,121,122,0.151595,-0.11014,0.982287,0.271402,-0.328069,0.904827,0.119441,-0.14438,0.982287); -f3(123,124,125,0.151595,-0.11014,0.982287,0.119441,-0.14438,0.982287,-0.0507986,0.0369073,0.998027); -f3(126,127,128,0.752205,0.297819,-0.587785,0.922445,0.116532,-0.368125,0.864484,0.342274,-0.368125); -f3(129,130,131,0.752205,0.297819,-0.587785,0.632398,0.0798904,-0.770513,0.802638,0.101397,-0.587785); -f3(132,133,134,0.344463,-0.73202,0.587785,0.174223,-0.913308,0.368125,0.151595,-0.794687,0.587785); -f3(135,136,137,0.752205,0.297819,-0.587785,0.802638,0.101397,-0.587785,0.922445,0.116532,-0.368125); -f3(138,139,140,0.185904,-0.0234851,-0.982287,0.174223,-0.0689797,-0.982287,0.39588,-0.15674,-0.904827); -f3(141,142,143,0.344463,-0.73202,0.587785,0.151595,-0.794687,0.587785,0.271402,-0.576758,0.770513); -f3(144,145,146,0.185904,-0.0234851,-0.982287,-0.0583811,0.0231147,-0.998027,0.174223,-0.0689797,-0.982287); -f3(147,148,149,0.185904,-0.0234851,-0.982287,0.39588,-0.15674,-0.904827,0.422422,-0.0533643,-0.904827); -f3(150,151,152,-0.433493,0.314951,-0.844328,-0.341549,0.412862,-0.844328,-0.196975,0.238102,-0.951057); -f3(153,154,155,-0.0622954,-0.990157,-0.125333,-0.30658,-0.943557,-0.125333,-0.0622954,-0.990157,0.125333); -f3(156,157,158,-0.433493,0.314951,-0.844328,-0.196975,0.238102,-0.951057,-0.25,0.181636,-0.951057); -f3(159,160,161,-0.0622954,-0.990157,-0.125333,-0.287317,-0.88427,-0.368125,-0.30658,-0.943557,-0.125333); -f3(162,163,164,-0.433493,0.314951,-0.844328,-0.464662,0.56168,-0.684547,-0.341549,0.412862,-0.844328); -f3(165,166,167,0.767913,-0.422164,0.481754,0.6388,-0.599873,0.481754,0.706067,-0.663041,0.24869); -f3(168,169,170,-0.341549,-0.538195,-0.770513,-0.31038,-0.291466,-0.904827,-0.464662,-0.436347,-0.770513); -f3(171,172,173,0.767913,-0.422164,0.481754,0.706067,-0.663041,0.24869,0.848776,-0.466619,0.24869); -f3(174,175,176,-0.341549,-0.538195,-0.770513,-0.589748,-0.55381,-0.587785,-0.433493,-0.683076,-0.587785); -f3(177,178,179,-0.341549,-0.538195,-0.770513,-0.464662,-0.436347,-0.770513,-0.589748,-0.55381,-0.587785); -f3(180,181,182,0.16558,-0.260912,0.951057,0.0954915,-0.293893,0.951057,0.28711,-0.452414,0.844328); -f3(183,184,185,0.0550238,0.0302496,-0.998027,0.299309,0.0768494,-0.951057,0.0608178,0.0156154,-0.998027); -f3(186,187,188,0.0550238,0.0302496,-0.998027,0.0608178,0.0156154,-0.998027,-0.181494,-0.0465998,-0.982287); -f3(189,190,191,0.0550238,0.0302496,-0.998027,-0.181494,-0.0465998,-0.982287,-0.164203,-0.0902716,-0.982287); -f3(192,193,194,-0.412403,0.8764,-0.24869,-0.425779,0.904827,0,-0.187381,0.982287,0); -f3(195,196,197,-0.412403,0.8764,-0.24869,-0.181494,0.951427,-0.24869,-0.164203,0.860785,-0.481754); -f3(198,199,200,-0.412403,0.8764,-0.24869,-0.164203,0.860785,-0.481754,-0.373113,0.792906,-0.481754); -f3(201,202,203,-0.412403,0.8764,-0.24869,-0.187381,0.982287,0,-0.181494,0.951427,-0.24869); -f3(204,205,206,-0.72322,-0.091364,0.684547,-0.72322,0.091364,0.684547,-0.869397,0.10983,0.481754); -f3(207,208,209,-0.72322,-0.091364,0.684547,-0.869397,0.10983,0.481754,-0.869397,-0.10983,0.481754); -f3(210,211,212,-0.0267349,0.424939,0.904827,0.0797831,0.418238,0.904827,-0.0117658,0.187012,0.982287); -f3(213,214,215,0.39588,0.841287,0.368125,0.632398,0.764437,0.125333,0.592662,0.716405,0.368125); -f3(216,217,218,0.39588,0.841287,0.368125,0.592662,0.716405,0.368125,0.344463,0.73202,0.587785); -f3(219,220,221,-0.0583811,0.0231147,0.998027,0.151595,-0.11014,0.982287,-0.0507986,0.0369073,0.998027); -f3(222,223,224,-0.0583811,0.0231147,0.998027,-0.0507986,0.0369073,0.998027,-0.25,0.181636,0.951057); -f3(225,226,227,-0.0583811,0.0231147,0.998027,-0.25,0.181636,0.951057,-0.287317,0.113757,0.951057); -f3(228,229,230,0.406309,-0.491144,0.770513,0.344463,-0.73202,0.587785,0.271402,-0.576758,0.770513); -f3(231,232,233,0.406309,-0.491144,0.770513,0.181288,-0.385257,0.904827,0.271402,-0.328069,0.904827); -f3(234,235,236,0.752205,0.546509,-0.368125,0.864484,0.342274,-0.368125,0.802638,0.58315,-0.125333); -f3(237,238,239,0.406309,-0.491144,0.770513,0.271402,-0.576758,0.770513,0.181288,-0.385257,0.904827); -f3(240,241,242,0.422422,0.0533643,-0.904827,0.422422,-0.0533643,-0.904827,0.632398,0.0798904,-0.770513); -f3(243,244,245,0.185904,-0.974542,0.125333,-0.0622954,-0.990157,-0.125333,-0.0622954,-0.990157,0.125333); -f3(246,247,248,0.185904,-0.974542,0.125333,-0.0622954,-0.990157,0.125333,0.174223,-0.913308,0.368125); -f3(249,250,251,-0.25,-0.769421,-0.587785,-0.433493,-0.683076,-0.587785,-0.498199,-0.785036,-0.368125); -f3(252,253,254,-0.287317,0.113757,-0.951057,-0.25,0.181636,-0.951057,-0.0583811,0.0231147,-0.998027); -f3(255,256,257,0.938153,-0.240877,0.24869,0.968583,-0.24869,0,0.968583,0,0.24869); -f3(258,259,260,-0.25,-0.769421,-0.587785,-0.341549,-0.538195,-0.770513,-0.433493,-0.683076,-0.587785); -f3(261,262,263,0.938153,-0.240877,0.24869,0.968583,0,0.24869,0.876307,0,0.481754); -f3(264,265,266,-0.25,-0.769421,-0.587785,-0.498199,-0.785036,-0.368125,-0.287317,-0.88427,-0.368125); -f3(267,268,269,0.938153,-0.240877,0.24869,0.848776,-0.466619,0.24869,0.968583,-0.24869,0); -f3(270,271,272,-0.136595,-0.128271,-0.982287,-0.373113,-0.205121,-0.904827,-0.31038,-0.291466,-0.904827); -f3(273,274,275,-0.136595,-0.128271,-0.982287,0.0550238,0.0302496,-0.998027,-0.164203,-0.0902716,-0.982287); -f3(276,277,278,-0.558579,0.675206,-0.481754,-0.373113,0.792906,-0.481754,-0.464662,0.56168,-0.684547); -f3(279,280,281,-0.136595,-0.128271,-0.982287,-0.164203,-0.0902716,-0.982287,-0.373113,-0.205121,-0.904827); -f3(282,283,284,-0.814769,-0.32259,0.481754,-0.869397,-0.10983,0.481754,-0.960946,-0.121396,0.24869); -f3(285,286,287,0.390601,-0.366799,0.844328,0.16558,-0.260912,0.951057,0.28711,-0.452414,0.844328); -f3(288,289,290,0.390601,-0.366799,0.844328,0.28711,-0.452414,0.844328,0.390601,-0.615489,0.684547); -f3(291,292,293,0.390601,-0.366799,0.844328,0.390601,-0.615489,0.684547,0.531395,-0.499013,0.684547); -f3(294,295,296,-0.814769,-0.32259,0.481754,-0.960946,-0.121396,0.24869,-0.900566,-0.356559,0.24869); -f3(297,298,299,-0.057904,0.17821,0.982287,-0.0117658,0.187012,0.982287,0.0194033,-0.0597173,0.998027); -f3(300,301,302,0.518993,0.133255,-0.844328,0.309017,0,-0.951057,0.299309,0.0768494,-0.951057); -f3(303,304,305,-0.057904,0.17821,0.982287,-0.0267349,0.424939,0.904827,-0.0117658,0.187012,0.982287); -f3(306,307,308,0.518993,0.133255,-0.844328,0.535827,0,-0.844328,0.309017,0,-0.951057); -f3(309,310,311,0.151595,0.794687,0.587785,0.344463,0.73202,0.587785,0.119441,0.626133,0.770513); -f3(312,313,314,0.151595,0.794687,0.587785,0.39588,0.841287,0.368125,0.344463,0.73202,0.587785); -f3(315,316,317,-0.30658,0.0387301,0.951057,-0.287317,0.113757,0.951057,-0.531602,0.0671569,0.844328); -f3(318,319,320,0.632398,0.764437,-0.125333,0.752205,0.546509,-0.368125,0.802638,0.58315,-0.125333); -f3(321,322,323,0.344463,-0.250267,0.904827,0.271402,-0.328069,0.904827,0.151595,-0.11014,0.982287); -f3(324,325,326,0.632398,0.764437,-0.125333,0.802638,0.58315,-0.125333,0.632398,0.764437,0.125333); -f3(327,328,329,0.39588,-0.841287,0.368125,0.174223,-0.913308,0.368125,0.344463,-0.73202,0.587785); -f3(330,331,332,0.592662,0.234651,-0.770513,0.632398,0.0798904,-0.770513,0.752205,0.297819,-0.587785); -f3(333,334,335,0.592662,0.234651,-0.770513,0.422422,0.0533643,-0.904827,0.632398,0.0798904,-0.770513); -f3(336,337,338,0.39588,-0.841287,0.368125,0.185904,-0.974542,0.125333,0.174223,-0.913308,0.368125); -f3(339,340,341,-0.0622954,0.00786974,-0.998027,-0.287317,0.113757,-0.951057,-0.0583811,0.0231147,-0.998027); -f3(342,343,344,-0.0583811,-0.927942,-0.368125,-0.287317,-0.88427,-0.368125,-0.0622954,-0.990157,-0.125333); -f3(345,346,347,-0.0622954,0.00786974,-0.998027,-0.0583811,0.0231147,-0.998027,0.185904,-0.0234851,-0.982287); -f3(348,349,350,-0.589748,0.428477,-0.684547,-0.558579,0.675206,-0.481754,-0.464662,0.56168,-0.684547); -f3(351,352,353,-0.589748,0.428477,-0.684547,-0.464662,0.56168,-0.684547,-0.433493,0.314951,-0.844328); -f3(354,355,356,-0.228144,-0.359497,-0.904827,-0.31038,-0.291466,-0.904827,-0.341549,-0.538195,-0.770513); -f3(357,358,359,0.6388,-0.351183,0.684547,0.6388,-0.599873,0.481754,0.767913,-0.422164,0.481754); -f3(360,361,362,-0.7836,-0.569319,0.24869,-0.900566,-0.356559,0.24869,-0.809017,-0.587785,0); -f3(363,364,365,0.6388,-0.351183,0.684547,0.531395,-0.499013,0.684547,0.6388,-0.599873,0.481754); -f3(366,367,368,0.0336448,-0.0530158,0.998027,0.0194033,-0.0597173,0.998027,0.0954915,-0.293893,0.951057); -f3(369,370,371,0.270794,0.14887,-0.951057,0.299309,0.0768494,-0.951057,0.0550238,0.0302496,-0.998027); -f3(372,373,374,0.0336448,-0.0530158,0.998027,-0.057904,0.17821,0.982287,0.0194033,-0.0597173,0.998027); -f3(375,376,377,0.0336448,-0.0530158,0.998027,0.0954915,-0.293893,0.951057,0.16558,-0.260912,0.951057); -f3(378,379,380,-0.531602,-0.0671569,0.844328,-0.72322,0.091364,0.684547,-0.72322,-0.091364,0.684547); -f3(381,382,383,-0.531602,-0.0671569,0.844328,-0.531602,0.0671569,0.844328,-0.72322,0.091364,0.684547); -f3(384,385,386,-0.0400242,0.636166,0.770513,0.119441,0.626133,0.770513,0.0797831,0.418238,0.904827); -f3(387,388,389,-0.0400242,0.636166,0.770513,0.0797831,0.418238,0.904827,-0.0267349,0.424939,0.904827); -f3(390,391,392,-0.0400242,0.636166,0.770513,0.151595,0.794687,0.587785,0.119441,0.626133,0.770513); -f3(393,394,395,0.422422,0.897692,0.125333,0.632398,0.764437,0.125333,0.39588,0.841287,0.368125); -f3(396,397,398,-0.531602,-0.0671569,0.844328,-0.30658,0.0387301,0.951057,-0.531602,0.0671569,0.844328); -f3(399,400,401,0.422422,0.897692,0.125333,0.632398,0.764437,-0.125333,0.632398,0.764437,0.125333); -f3(402,403,404,0.174223,-0.0689797,0.982287,0.344463,-0.250267,0.904827,0.151595,-0.11014,0.982287); -f3(405,406,407,0.654508,0.475528,-0.587785,0.752205,0.297819,-0.587785,0.864484,0.342274,-0.368125); -f3(408,409,410,0.174223,-0.0689797,0.982287,0.151595,-0.11014,0.982287,-0.0583811,0.0231147,0.998027); -f3(411,412,413,0.654508,0.475528,-0.587785,0.592662,0.234651,-0.770513,0.752205,0.297819,-0.587785); -f3(414,415,416,0.515687,-0.623358,0.587785,0.39588,-0.841287,0.368125,0.344463,-0.73202,0.587785); -f3(417,418,419,0.654508,0.475528,-0.587785,0.864484,0.342274,-0.368125,0.752205,0.546509,-0.368125); -f3(420,421,422,0.185904,0.0234851,-0.982287,0.422422,-0.0533643,-0.904827,0.422422,0.0533643,-0.904827); -f3(423,424,425,0.185904,0.0234851,-0.982287,-0.0622954,0.00786974,-0.998027,0.185904,-0.0234851,-0.982287); -f3(426,427,428,0.515687,-0.623358,0.587785,0.344463,-0.73202,0.587785,0.406309,-0.491144,0.770513); -f3(429,430,431,0.185904,0.0234851,-0.982287,0.185904,-0.0234851,-0.982287,0.422422,-0.0533643,-0.904827); -f3(432,433,434,-0.498199,0.197251,-0.844328,-0.25,0.181636,-0.951057,-0.287317,0.113757,-0.951057); -f3(435,436,437,0.185904,-0.974542,-0.125333,-0.0622954,-0.990157,-0.125333,0.185904,-0.974542,0.125333); -f3(438,439,440,-0.498199,0.197251,-0.844328,-0.589748,0.428477,-0.684547,-0.433493,0.314951,-0.844328); -f3(441,442,443,0.185904,-0.974542,-0.125333,-0.0583811,-0.927942,-0.368125,-0.0622954,-0.990157,-0.125333); -f3(444,445,446,-0.498199,0.197251,-0.844328,-0.433493,0.314951,-0.844328,-0.25,0.181636,-0.951057); -f3(447,448,449,0.848776,-0.217929,0.481754,0.848776,-0.466619,0.24869,0.938153,-0.240877,0.24869); -f3(450,451,452,-0.196975,-0.606226,-0.770513,-0.341549,-0.538195,-0.770513,-0.25,-0.769421,-0.587785); -f3(453,454,455,0.848776,-0.217929,0.481754,0.938153,-0.240877,0.24869,0.876307,0,0.481754); -f3(456,457,458,0.848776,-0.217929,0.481754,0.767913,-0.422164,0.481754,0.848776,-0.466619,0.24869); -f3(459,460,461,-0.196975,-0.606226,-0.770513,-0.228144,-0.359497,-0.904827,-0.341549,-0.538195,-0.770513); -f3(462,463,464,-0.617398,0.746306,-0.24869,-0.637424,0.770513,0,-0.425779,0.904827,0); -f3(465,466,467,-0.617398,0.746306,-0.24869,-0.373113,0.792906,-0.481754,-0.558579,0.675206,-0.481754); -f3(468,469,470,0.0457723,0.0429831,-0.998027,0.270794,0.14887,-0.951057,0.0550238,0.0302496,-0.998027); -f3(471,472,473,-0.617398,0.746306,-0.24869,-0.425779,0.904827,0,-0.412403,0.8764,-0.24869); -f3(474,475,476,0.0457723,0.0429831,-0.998027,0.0550238,0.0302496,-0.998027,-0.136595,-0.128271,-0.982287); -f3(477,478,479,-0.617398,0.746306,-0.24869,-0.412403,0.8764,-0.24869,-0.373113,0.792906,-0.481754); -f3(480,481,482,-0.677778,-0.268351,0.684547,-0.72322,-0.091364,0.684547,-0.869397,-0.10983,0.481754); -f3(483,484,485,0.225264,-0.211537,0.951057,0.16558,-0.260912,0.951057,0.390601,-0.366799,0.844328); -f3(486,487,488,-0.131573,0.40494,0.904827,-0.0267349,0.424939,0.904827,-0.057904,0.17821,0.982287); -f3(489,490,491,-0.677778,-0.268351,0.684547,-0.869397,-0.10983,0.481754,-0.814769,-0.32259,0.481754); -f3(492,493,494,0.706067,0.181287,-0.684547,0.535827,0,-0.844328,0.518993,0.133255,-0.844328); -f3(495,496,497,0.174223,0.913308,0.368125,0.39588,0.841287,0.368125,0.151595,0.794687,0.587785); -f3(498,499,500,0.174223,0.913308,0.368125,0.422422,0.897692,0.125333,0.39588,0.841287,0.368125); -f3(501,502,503,0.706067,0.181287,-0.684547,0.728969,0,-0.684547,0.535827,0,-0.844328); -f3(504,505,506,0.706067,0.181287,-0.684547,0.876307,0,-0.481754,0.728969,0,-0.684547); -f3(507,508,509,-0.0622954,0.00786974,0.998027,-0.0583811,0.0231147,0.998027,-0.287317,0.113757,0.951057); -f3(510,511,512,0.592662,0.716405,-0.368125,0.752205,0.546509,-0.368125,0.632398,0.764437,-0.125333); -f3(513,514,515,-0.0622954,0.00786974,0.998027,-0.287317,0.113757,0.951057,-0.30658,0.0387301,0.951057); -f3(516,517,518,-0.0622954,0.00786974,0.998027,0.174223,-0.0689797,0.982287,-0.0583811,0.0231147,0.998027); -f3(519,520,521,0.515687,-0.374668,0.770513,0.406309,-0.491144,0.770513,0.271402,-0.328069,0.904827); -f3(522,523,524,0.39588,0.15674,-0.904827,0.422422,0.0533643,-0.904827,0.592662,0.234651,-0.770513); -f3(525,526,527,0.515687,-0.374668,0.770513,0.271402,-0.328069,0.904827,0.344463,-0.250267,0.904827); -f3(528,529,530,0.515687,-0.374668,0.770513,0.515687,-0.623358,0.587785,0.406309,-0.491144,0.770513); -f3(531,532,533,0.422422,-0.897692,0.125333,0.185904,-0.974542,0.125333,0.39588,-0.841287,0.368125); -f3(534,535,536,-0.30658,0.0387301,-0.951057,-0.287317,0.113757,-0.951057,-0.0622954,0.00786974,-0.998027); -f3(537,538,539,0.422422,-0.897692,0.125333,0.185904,-0.974542,-0.125333,0.185904,-0.974542,0.125333); -f3(540,541,542,-0.0507986,-0.807421,-0.587785,-0.287317,-0.88427,-0.368125,-0.0583811,-0.927942,-0.368125); -f3(543,544,545,-0.708947,0.51508,-0.481754,-0.558579,0.675206,-0.481754,-0.589748,0.428477,-0.684547); -f3(546,547,548,0.469549,-0.258137,0.844328,0.390601,-0.366799,0.844328,0.531395,-0.499013,0.684547); -f3(549,550,551,-0.0507986,-0.807421,-0.587785,-0.25,-0.769421,-0.587785,-0.287317,-0.88427,-0.368125); -f3(552,553,554,-0.0507986,-0.807421,-0.587785,-0.196975,-0.606226,-0.770513,-0.25,-0.769421,-0.587785); -f3(555,556,557,0.469549,-0.258137,0.844328,0.225264,-0.211537,0.951057,0.390601,-0.366799,0.844328); -f3(558,559,560,-0.100404,-0.158211,-0.982287,-0.136595,-0.128271,-0.982287,-0.31038,-0.291466,-0.904827); -f3(561,562,563,0.968583,0,0.24869,0.968583,-0.24869,0,1,0,-0); -f3(564,565,566,0.469549,-0.258137,0.844328,0.531395,-0.499013,0.684547,0.6388,-0.351183,0.684547); -f3(567,568,569,-0.100404,-0.158211,-0.982287,-0.31038,-0.291466,-0.904827,-0.228144,-0.359497,-0.904827); -f3(570,571,572,-0.100404,0.158211,0.982287,-0.057904,0.17821,0.982287,0.0336448,-0.0530158,0.998027); -f3(573,574,575,-0.100404,0.158211,0.982287,-0.131573,0.40494,0.904827,-0.057904,0.17821,0.982287); -f3(576,577,578,-0.708947,-0.51508,0.481754,-0.900566,-0.356559,0.24869,-0.7836,-0.569319,0.24869); -f3(579,580,581,-0.0507986,0.807421,0.587785,0.174223,0.913308,0.368125,0.151595,0.794687,0.587785); -f3(582,583,584,-0.708947,-0.51508,0.481754,-0.814769,-0.32259,0.481754,-0.900566,-0.356559,0.24869); -f3(585,586,587,-0.0507986,0.807421,0.587785,0.151595,0.794687,0.587785,-0.0400242,0.636166,0.770513); -f3(588,589,590,0.469549,0.258137,-0.844328,0.518993,0.133255,-0.844328,0.299309,0.0768494,-0.951057); -f3(591,592,593,0.422422,0.897692,-0.125333,0.592662,0.716405,-0.368125,0.632398,0.764437,-0.125333); -f3(594,595,596,0.469549,0.258137,-0.844328,0.299309,0.0768494,-0.951057,0.270794,0.14887,-0.951057); -f3(597,598,599,0.422422,0.897692,-0.125333,0.632398,0.764437,-0.125333,0.422422,0.897692,0.125333); -f3(600,601,602,0.515687,0.374668,-0.770513,0.592662,0.234651,-0.770513,0.654508,0.475528,-0.587785); -f3(603,604,605,-0.30658,-0.0387301,0.951057,-0.30658,0.0387301,0.951057,-0.531602,-0.0671569,0.844328); -f3(606,607,608,0.515687,0.374668,-0.770513,0.39588,0.15674,-0.904827,0.592662,0.234651,-0.770513); -f3(609,610,611,0.39588,-0.15674,0.904827,0.344463,-0.250267,0.904827,0.174223,-0.0689797,0.982287); -f3(612,613,614,-0.0622954,-0.00786974,-0.998027,-0.30658,0.0387301,-0.951057,-0.0622954,0.00786974,-0.998027); -f3(615,616,617,-0.0622954,-0.00786974,-0.998027,-0.0622954,0.00786974,-0.998027,0.185904,0.0234851,-0.982287); -f3(618,619,620,0.592662,-0.716405,0.368125,0.422422,-0.897692,0.125333,0.39588,-0.841287,0.368125); -f3(621,622,623,-0.677778,0.268351,-0.684547,-0.589748,0.428477,-0.684547,-0.498199,0.197251,-0.844328); -f3(624,625,626,-0.677778,0.268351,-0.684547,-0.708947,0.51508,-0.481754,-0.589748,0.428477,-0.684547); -f3(627,628,629,0.706067,-0.181287,0.684547,0.848776,-0.217929,0.481754,0.876307,0,0.481754); -f3(630,631,632,0.592662,-0.716405,0.368125,0.39588,-0.841287,0.368125,0.515687,-0.623358,0.587785); -f3(633,634,635,0.706067,-0.181287,0.684547,0.876307,0,0.481754,0.728969,0,0.684547); -f3(636,637,638,0.706067,-0.181287,0.684547,0.767913,-0.422164,0.481754,0.848776,-0.217929,0.481754); -f3(639,640,641,0.706067,-0.181287,0.684547,0.6388,-0.351183,0.684547,0.767913,-0.422164,0.481754); -f3(642,643,644,0.174223,-0.913308,-0.368125,-0.0583811,-0.927942,-0.368125,0.185904,-0.974542,-0.125333); -f3(645,646,647,0.0457723,-0.0429831,0.998027,0.0336448,-0.0530158,0.998027,0.16558,-0.260912,0.951057); -f3(648,649,650,0.0457723,-0.0429831,0.998027,0.16558,-0.260912,0.951057,0.225264,-0.211537,0.951057); -f3(651,652,653,-0.196975,0.606226,0.770513,-0.0267349,0.424939,0.904827,-0.131573,0.40494,0.904827); -f3(654,655,656,-0.196975,0.606226,0.770513,-0.0400242,0.636166,0.770513,-0.0267349,0.424939,0.904827); -f3(657,658,659,-0.131573,-0.40494,-0.904827,-0.228144,-0.359497,-0.904827,-0.196975,-0.606226,-0.770513); -f3(660,661,662,-0.617398,-0.746306,0.24869,-0.7836,-0.569319,0.24869,-0.809017,-0.587785,0); -f3(663,664,665,-0.617398,-0.746306,0.24869,-0.809017,-0.587785,0,-0.637424,-0.770513,0); -f3(666,667,668,-0.196975,0.606226,0.770513,-0.0507986,0.807421,0.587785,-0.0400242,0.636166,0.770513); -f3(669,670,671,0.225264,0.211537,-0.951057,0.270794,0.14887,-0.951057,0.0457723,0.0429831,-0.998027); -f3(672,673,674,0.185904,0.974542,0.125333,0.422422,0.897692,-0.125333,0.422422,0.897692,0.125333); -f3(675,676,677,0.185904,0.974542,0.125333,0.422422,0.897692,0.125333,0.174223,0.913308,0.368125); -f3(678,679,680,-0.498199,-0.197251,0.844328,-0.30658,-0.0387301,0.951057,-0.531602,-0.0671569,0.844328); -f3(681,682,683,0.515687,0.623358,-0.587785,0.654508,0.475528,-0.587785,0.752205,0.546509,-0.368125); -f3(684,685,686,0.515687,0.623358,-0.587785,0.752205,0.546509,-0.368125,0.592662,0.716405,-0.368125); -f3(687,688,689,-0.498199,-0.197251,0.844328,-0.531602,-0.0671569,0.844328,-0.72322,-0.091364,0.684547); -f3(690,691,692,0.515687,0.623358,-0.587785,0.515687,0.374668,-0.770513,0.654508,0.475528,-0.587785); -f3(693,694,695,-0.498199,-0.197251,0.844328,-0.72322,-0.091364,0.684547,-0.677778,-0.268351,0.684547); -f3(696,697,698,0.174223,0.0689797,-0.982287,0.185904,0.0234851,-0.982287,0.422422,0.0533643,-0.904827); -f3(699,700,701,0.174223,0.0689797,-0.982287,0.422422,0.0533643,-0.904827,0.39588,0.15674,-0.904827); -f3(702,703,704,0.848776,0.217929,-0.481754,0.876307,0,-0.481754,0.706067,0.181287,-0.684547); -f3(705,706,707,0.174223,0.0689797,-0.982287,-0.0622954,-0.00786974,-0.998027,0.185904,0.0234851,-0.982287); -f3(708,709,710,-0.531602,0.0671569,-0.844328,-0.677778,0.268351,-0.684547,-0.498199,0.197251,-0.844328); -f3(711,712,713,0.185904,-0.0234851,0.982287,0.39588,-0.15674,0.904827,0.174223,-0.0689797,0.982287); -f3(714,715,716,-0.531602,0.0671569,-0.844328,-0.498199,0.197251,-0.844328,-0.287317,0.113757,-0.951057); -f3(717,718,719,0.185904,-0.0234851,0.982287,0.174223,-0.0689797,0.982287,-0.0622954,0.00786974,0.998027); -f3(720,721,722,-0.531602,0.0671569,-0.844328,-0.287317,0.113757,-0.951057,-0.30658,0.0387301,-0.951057); -f3(723,724,725,-0.7836,0.569319,-0.24869,-0.809017,0.587785,0,-0.637424,0.770513,0); -f3(726,727,728,-0.7836,0.569319,-0.24869,-0.929776,0.368125,0,-0.809017,0.587785,0); -f3(729,730,731,-0.7836,0.569319,-0.24869,-0.617398,0.746306,-0.24869,-0.558579,0.675206,-0.481754); -f3(732,733,734,-0.7836,0.569319,-0.24869,-0.637424,0.770513,0,-0.617398,0.746306,-0.24869); -f3(735,736,737,-0.7836,0.569319,-0.24869,-0.558579,0.675206,-0.481754,-0.708947,0.51508,-0.481754); -f3(738,739,740,0.654508,-0.475528,0.587785,0.592662,-0.716405,0.368125,0.515687,-0.623358,0.587785); -f3(741,742,743,0.654508,-0.475528,0.587785,0.515687,-0.623358,0.587785,0.515687,-0.374668,0.770513); -f3(744,745,746,0.422422,-0.897692,-0.125333,0.185904,-0.974542,-0.125333,0.422422,-0.897692,0.125333); -f3(747,748,749,0.270794,-0.14887,0.951057,0.225264,-0.211537,0.951057,0.469549,-0.258137,0.844328); -f3(750,751,752,-0.228144,0.359497,0.904827,-0.131573,0.40494,0.904827,-0.100404,0.158211,0.982287); -f3(753,754,755,0.422422,-0.897692,-0.125333,0.174223,-0.913308,-0.368125,0.185904,-0.974542,-0.125333); -f3(756,757,758,-0.0583811,0.927942,0.368125,0.185904,0.974542,0.125333,0.174223,0.913308,0.368125); -f3(759,760,761,-0.0400242,-0.636166,-0.770513,-0.196975,-0.606226,-0.770513,-0.0507986,-0.807421,-0.587785); -f3(762,763,764,-0.0583811,0.927942,0.368125,0.174223,0.913308,0.368125,-0.0507986,0.807421,0.587785); -f3(765,766,767,-0.0400242,-0.636166,-0.770513,-0.131573,-0.40494,-0.904827,-0.196975,-0.606226,-0.770513); -f3(768,769,770,0.0336448,0.0530158,-0.998027,0.225264,0.211537,-0.951057,0.0457723,0.0429831,-0.998027); -f3(771,772,773,0.39588,0.841287,-0.368125,0.592662,0.716405,-0.368125,0.422422,0.897692,-0.125333); -f3(774,775,776,0.0336448,0.0530158,-0.998027,-0.136595,-0.128271,-0.982287,-0.100404,-0.158211,-0.982287); -f3(777,778,779,0.0336448,0.0530158,-0.998027,0.0457723,0.0429831,-0.998027,-0.136595,-0.128271,-0.982287); -f3(780,781,782,-0.589748,-0.428477,0.684547,-0.814769,-0.32259,0.481754,-0.708947,-0.51508,0.481754); -f3(783,784,785,0.344463,0.250267,-0.904827,0.39588,0.15674,-0.904827,0.515687,0.374668,-0.770513); -f3(786,787,788,-0.589748,-0.428477,0.684547,-0.677778,-0.268351,0.684547,-0.814769,-0.32259,0.481754); -f3(789,790,791,-0.30658,-0.0387301,-0.951057,-0.30658,0.0387301,-0.951057,-0.0622954,-0.00786974,-0.998027); -f3(792,793,794,0.6388,0.351183,-0.684547,0.518993,0.133255,-0.844328,0.469549,0.258137,-0.844328); -f3(795,796,797,0.6388,0.351183,-0.684547,0.848776,0.217929,-0.481754,0.706067,0.181287,-0.684547); -f3(798,799,800,0.6388,0.351183,-0.684547,0.706067,0.181287,-0.684547,0.518993,0.133255,-0.844328); -f3(801,802,803,-0.814769,0.32259,-0.481754,-0.708947,0.51508,-0.481754,-0.677778,0.268351,-0.684547); -f3(804,805,806,-0.0622954,-0.00786974,0.998027,-0.0622954,0.00786974,0.998027,-0.30658,0.0387301,0.951057); -f3(807,808,809,-0.0622954,-0.00786974,0.998027,-0.30658,0.0387301,0.951057,-0.30658,-0.0387301,0.951057); -f3(810,811,812,0.518993,-0.133255,0.844328,0.6388,-0.351183,0.684547,0.706067,-0.181287,0.684547); -f3(813,814,815,0.518993,-0.133255,0.844328,0.728969,0,0.684547,0.535827,0,0.844328); -f3(816,817,818,0.518993,-0.133255,0.844328,0.535827,0,0.844328,0.309017,0,0.951057); -f3(819,820,821,0.518993,-0.133255,0.844328,0.706067,-0.181287,0.684547,0.728969,0,0.684547); -f3(822,823,824,0.518993,-0.133255,0.844328,0.469549,-0.258137,0.844328,0.6388,-0.351183,0.684547); -f3(825,826,827,0.518993,-0.133255,0.844328,0.270794,-0.14887,0.951057,0.469549,-0.258137,0.844328); -f3(828,829,830,-0.0622954,-0.00786974,0.998027,0.185904,-0.0234851,0.982287,-0.0622954,0.00786974,0.998027); -f3(831,832,833,0.592662,-0.234651,0.770513,0.344463,-0.250267,0.904827,0.39588,-0.15674,0.904827); -f3(834,835,836,-0.136595,0.128271,0.982287,0.0336448,-0.0530158,0.998027,0.0457723,-0.0429831,0.998027); -f3(837,838,839,-0.136595,0.128271,0.982287,-0.100404,0.158211,0.982287,0.0336448,-0.0530158,0.998027); -f3(840,841,842,-0.25,0.769421,0.587785,-0.0507986,0.807421,0.587785,-0.196975,0.606226,0.770513); -f3(843,844,845,-0.25,0.769421,0.587785,-0.0583811,0.927942,0.368125,-0.0507986,0.807421,0.587785); -f3(846,847,848,0.592662,-0.234651,0.770513,0.654508,-0.475528,0.587785,0.515687,-0.374668,0.770513); -f3(849,850,851,0.592662,-0.234651,0.770513,0.515687,-0.374668,0.770513,0.344463,-0.250267,0.904827); -f3(852,853,854,0.632398,-0.764437,0.125333,0.422422,-0.897692,0.125333,0.592662,-0.716405,0.368125); -f3(855,856,857,0.185904,0.974542,-0.125333,0.39588,0.841287,-0.368125,0.422422,0.897692,-0.125333); -f3(858,859,860,0.632398,-0.764437,0.125333,0.422422,-0.897692,-0.125333,0.422422,-0.897692,0.125333); -f3(861,862,863,0.151595,-0.794687,-0.587785,-0.0507986,-0.807421,-0.587785,-0.0583811,-0.927942,-0.368125); -f3(864,865,866,0.185904,0.974542,-0.125333,0.422422,0.897692,-0.125333,0.185904,0.974542,0.125333); -f3(867,868,869,0.151595,-0.794687,-0.587785,-0.0400242,-0.636166,-0.770513,-0.0507986,-0.807421,-0.587785); -f3(870,871,872,0.406309,0.491144,-0.770513,0.515687,0.374668,-0.770513,0.515687,0.623358,-0.587785); -f3(873,874,875,0.151595,-0.794687,-0.587785,-0.0583811,-0.927942,-0.368125,0.174223,-0.913308,-0.368125); -f3(876,877,878,0.406309,0.491144,-0.770513,0.344463,0.250267,-0.904827,0.515687,0.374668,-0.770513); -f3(879,880,881,-0.057904,-0.17821,-0.982287,-0.100404,-0.158211,-0.982287,-0.228144,-0.359497,-0.904827); -f3(882,883,884,-0.057904,-0.17821,-0.982287,0.0336448,0.0530158,-0.998027,-0.100404,-0.158211,-0.982287); -f3(885,886,887,-0.057904,-0.17821,-0.982287,-0.228144,-0.359497,-0.904827,-0.131573,-0.40494,-0.904827); -f3(888,889,890,-0.558579,-0.675206,0.481754,-0.7836,-0.569319,0.24869,-0.617398,-0.746306,0.24869); -f3(891,892,893,-0.0583811,-0.0231147,-0.998027,-0.0622954,-0.00786974,-0.998027,0.174223,0.0689797,-0.982287); -f3(894,895,896,-0.0583811,-0.0231147,-0.998027,-0.30658,-0.0387301,-0.951057,-0.0622954,-0.00786974,-0.998027); -f3(897,898,899,-0.72322,0.091364,-0.684547,-0.677778,0.268351,-0.684547,-0.531602,0.0671569,-0.844328); -f3(900,901,902,-0.72322,0.091364,-0.684547,-0.814769,0.32259,-0.481754,-0.677778,0.268351,-0.684547); -f3(903,904,905,-0.558579,-0.675206,0.481754,-0.708947,-0.51508,0.481754,-0.7836,-0.569319,0.24869); -f3(906,907,908,0.0550238,-0.0302496,0.998027,0.0457723,-0.0429831,0.998027,0.225264,-0.211537,0.951057); -f3(909,910,911,0.0550238,-0.0302496,0.998027,-0.136595,0.128271,0.982287,0.0457723,-0.0429831,0.998027); -f3(912,913,914,0.390601,0.366799,-0.844328,0.469549,0.258137,-0.844328,0.270794,0.14887,-0.951057); -f3(915,916,917,0.390601,0.366799,-0.844328,0.270794,0.14887,-0.951057,0.225264,0.211537,-0.951057); -f3(918,919,920,0.0550238,-0.0302496,0.998027,0.225264,-0.211537,0.951057,0.270794,-0.14887,0.951057); -f3(921,922,923,0.390601,0.366799,-0.844328,0.6388,0.351183,-0.684547,0.469549,0.258137,-0.844328); -f3(924,925,926,-0.341549,0.538195,0.770513,-0.196975,0.606226,0.770513,-0.131573,0.40494,0.904827); -f3(927,928,929,-0.341549,0.538195,0.770513,-0.25,0.769421,0.587785,-0.196975,0.606226,0.770513); -f3(930,931,932,-0.341549,0.538195,0.770513,-0.131573,0.40494,0.904827,-0.228144,0.359497,0.904827); -f3(933,934,935,-0.287317,-0.113757,0.951057,-0.30658,-0.0387301,0.951057,-0.498199,-0.197251,0.844328); -f3(936,937,938,0.938153,0.240877,-0.24869,0.968583,0.24869,-0,1,0,-0); -f3(939,940,941,0.938153,0.240877,-0.24869,0.876307,0.481754,-0,0.968583,0.24869,-0); -f3(942,943,944,0.938153,0.240877,-0.24869,0.876307,0,-0.481754,0.848776,0.217929,-0.481754); -f3(945,946,947,-0.0622954,0.990157,0.125333,0.185904,0.974542,-0.125333,0.185904,0.974542,0.125333); -f3(948,949,950,-0.0622954,0.990157,0.125333,0.185904,0.974542,0.125333,-0.0583811,0.927942,0.368125); -f3(951,952,953,0.938153,0.240877,-0.24869,0.968583,0,-0.24869,0.876307,0,-0.481754); -f3(954,955,956,0.938153,0.240877,0.24869,1,0,-0,0.968583,0.24869,-0); -f3(957,958,959,0.938153,0.240877,-0.24869,1,0,-0,0.968583,0,-0.24869); -f3(960,961,962,0.344463,0.73202,-0.587785,0.515687,0.623358,-0.587785,0.592662,0.716405,-0.368125); -f3(963,964,965,0.938153,0.240877,0.24869,0.968583,0.24869,-0,0.876307,0.481754,-0); -f3(966,967,968,0.344463,0.73202,-0.587785,0.592662,0.716405,-0.368125,0.39588,0.841287,-0.368125); -f3(969,970,971,0.938153,0.240877,0.24869,0.968583,0,0.24869,1,0,-0); -f3(972,973,974,0.422422,-0.0533643,0.904827,0.39588,-0.15674,0.904827,0.185904,-0.0234851,0.982287); -f3(975,976,977,0.344463,0.73202,-0.587785,0.406309,0.491144,-0.770513,0.515687,0.623358,-0.587785); -f3(978,979,980,0.848776,0.217929,0.481754,0.968583,0,0.24869,0.938153,0.240877,0.24869); -f3(981,982,983,0.848776,0.217929,0.481754,0.876307,0,0.481754,0.968583,0,0.24869); -f3(984,985,986,0.151595,0.11014,-0.982287,0.174223,0.0689797,-0.982287,0.39588,0.15674,-0.904827); -f3(987,988,989,0.752205,-0.546509,0.368125,0.632398,-0.764437,0.125333,0.592662,-0.716405,0.368125); -f3(990,991,992,0.151595,0.11014,-0.982287,0.39588,0.15674,-0.904827,0.344463,0.250267,-0.904827); -f3(993,994,995,0.752205,-0.546509,0.368125,0.592662,-0.716405,0.368125,0.654508,-0.475528,0.587785); -f3(996,997,998,0.848776,0.466619,0.24869,0.938153,0.240877,0.24869,0.876307,0.481754,-0); -f3(999,1000,1001,0.151595,0.11014,-0.982287,-0.0583811,-0.0231147,-0.998027,0.174223,0.0689797,-0.982287); -f3(1002,1003,1004,-0.531602,-0.0671569,-0.844328,-0.531602,0.0671569,-0.844328,-0.30658,0.0387301,-0.951057); -f3(1005,1006,1007,-0.531602,-0.0671569,-0.844328,-0.72322,0.091364,-0.684547,-0.531602,0.0671569,-0.844328); -f3(1008,1009,1010,-0.531602,-0.0671569,-0.844328,-0.30658,0.0387301,-0.951057,-0.30658,-0.0387301,-0.951057); -f3(1011,1012,1013,0.706067,0.181287,0.684547,0.876307,0,0.481754,0.848776,0.217929,0.481754); -f3(1014,1015,1016,0.39588,-0.841287,-0.368125,0.174223,-0.913308,-0.368125,0.422422,-0.897692,-0.125333); -f3(1017,1018,1019,0.706067,0.181287,0.684547,0.728969,0,0.684547,0.876307,0,0.481754); -f3(1020,1021,1022,-0.900566,0.356559,-0.24869,-0.929776,0.368125,0,-0.7836,0.569319,-0.24869); -f3(1023,1024,1025,-0.900566,0.356559,-0.24869,-0.992115,0.125333,0,-0.929776,0.368125,0); -f3(1026,1027,1028,-0.900566,0.356559,-0.24869,-0.7836,0.569319,-0.24869,-0.708947,0.51508,-0.481754); -f3(1029,1030,1031,-0.900566,0.356559,-0.24869,-0.708947,0.51508,-0.481754,-0.814769,0.32259,-0.481754); -f3(1032,1033,1034,-0.0267349,-0.424939,-0.904827,-0.131573,-0.40494,-0.904827,-0.0400242,-0.636166,-0.770513); -f3(1035,1036,1037,0.299309,-0.0768494,0.951057,0.270794,-0.14887,0.951057,0.518993,-0.133255,0.844328); -f3(1038,1039,1040,0.299309,-0.0768494,0.951057,0.518993,-0.133255,0.844328,0.309017,0,0.951057); -f3(1041,1042,1043,-0.31038,0.291466,0.904827,-0.228144,0.359497,0.904827,-0.100404,0.158211,0.982287); -f3(1044,1045,1046,0.767913,0.422164,0.481754,0.848776,0.217929,0.481754,0.938153,0.240877,0.24869); -f3(1047,1048,1049,0.767913,0.422164,0.481754,0.938153,0.240877,0.24869,0.848776,0.466619,0.24869); -f3(1050,1051,1052,0.16558,0.260912,-0.951057,0.225264,0.211537,-0.951057,0.0336448,0.0530158,-0.998027); -f3(1053,1054,1055,-0.31038,0.291466,0.904827,-0.100404,0.158211,0.982287,-0.136595,0.128271,0.982287); -f3(1056,1057,1058,0.706067,0.663041,0.24869,0.876307,0.481754,-0,0.728969,0.684547,-0); -f3(1059,1060,1061,0.706067,0.663041,0.24869,0.728969,0.684547,-0,0.535827,0.844328,-0); -f3(1062,1063,1064,-0.412403,-0.8764,0.24869,-0.617398,-0.746306,0.24869,-0.637424,-0.770513,0); -f3(1065,1066,1067,-0.412403,-0.8764,0.24869,-0.637424,-0.770513,0,-0.425779,-0.904827,0); -f3(1068,1069,1070,0.706067,0.663041,0.24869,0.848776,0.466619,0.24869,0.876307,0.481754,-0); -f3(1071,1072,1073,-0.287317,0.88427,0.368125,-0.0622954,0.990157,0.125333,-0.0583811,0.927942,0.368125); -f3(1074,1075,1076,0.518993,0.133255,0.844328,0.728969,0,0.684547,0.706067,0.181287,0.684547); -f3(1077,1078,1079,-0.287317,0.88427,0.368125,-0.0583811,0.927942,0.368125,-0.25,0.769421,0.587785); -f3(1080,1081,1082,0.518993,0.133255,0.844328,0.535827,0,0.844328,0.728969,0,0.684547); -f3(1083,1084,1085,0.518993,0.133255,0.844328,0.309017,0,0.951057,0.535827,0,0.844328); -f3(1086,1087,1088,0.174223,0.913308,-0.368125,0.39588,0.841287,-0.368125,0.185904,0.974542,-0.125333); -f3(1089,1090,1091,-0.433493,-0.314951,0.844328,-0.498199,-0.197251,0.844328,-0.677778,-0.268351,0.684547); -f3(1092,1093,1094,0.6388,0.351183,0.684547,0.706067,0.181287,0.684547,0.848776,0.217929,0.481754); -f3(1095,1096,1097,-0.433493,-0.314951,0.844328,-0.677778,-0.268351,0.684547,-0.589748,-0.428477,0.684547); -f3(1098,1099,1100,-0.433493,-0.314951,0.844328,-0.287317,-0.113757,0.951057,-0.498199,-0.197251,0.844328); -f3(1101,1102,1103,0.6388,0.351183,0.684547,0.848776,0.217929,0.481754,0.767913,0.422164,0.481754); -f3(1104,1105,1106,0.767913,0.422164,-0.481754,0.848776,0.217929,-0.481754,0.6388,0.351183,-0.684547); -f3(1107,1108,1109,0.271402,0.328069,-0.904827,0.344463,0.250267,-0.904827,0.406309,0.491144,-0.770513); -f3(1110,1111,1112,0.185904,0.0234851,0.982287,0.185904,-0.0234851,0.982287,-0.0622954,-0.00786974,0.998027); -f3(1113,1114,1115,0.6388,0.599873,0.481754,0.848776,0.466619,0.24869,0.706067,0.663041,0.24869); -f3(1116,1117,1118,-0.287317,-0.113757,-0.951057,-0.30658,-0.0387301,-0.951057,-0.0583811,-0.0231147,-0.998027); -f3(1119,1120,1121,0.6388,0.599873,0.481754,0.767913,0.422164,0.481754,0.848776,0.466619,0.24869); -f3(1122,1123,1124,0.185904,0.0234851,0.982287,0.422422,-0.0533643,0.904827,0.185904,-0.0234851,0.982287); -f3(1125,1126,1127,-0.869397,0.10983,-0.481754,-0.814769,0.32259,-0.481754,-0.72322,0.091364,-0.684547); -f3(1128,1129,1130,0.752205,-0.297819,0.587785,0.752205,-0.546509,0.368125,0.654508,-0.475528,0.587785); -f3(1131,1132,1133,0.299309,0.0768494,0.951057,0.309017,0,0.951057,0.518993,0.133255,0.844328); -f3(1134,1135,1136,-0.164203,0.0902716,0.982287,-0.136595,0.128271,0.982287,0.0550238,-0.0302496,0.998027); -f3(1137,1138,1139,0.752205,-0.297819,0.587785,0.654508,-0.475528,0.587785,0.592662,-0.234651,0.770513); -f3(1140,1141,1142,-0.164203,0.0902716,0.982287,-0.31038,0.291466,0.904827,-0.136595,0.128271,0.982287); -f3(1143,1144,1145,0.518993,0.817802,0.24869,0.706067,0.663041,0.24869,0.535827,0.844328,-0); -f3(1146,1147,1148,0.632398,-0.764437,-0.125333,0.39588,-0.841287,-0.368125,0.422422,-0.897692,-0.125333); -f3(1149,1150,1151,-0.433493,0.683076,0.587785,-0.25,0.769421,0.587785,-0.341549,0.538195,0.770513); -f3(1152,1153,1154,-0.433493,0.683076,0.587785,-0.287317,0.88427,0.368125,-0.25,0.769421,0.587785); -f3(1155,1156,1157,0.469549,0.258137,0.844328,0.518993,0.133255,0.844328,0.706067,0.181287,0.684547); -f3(1158,1159,1160,0.632398,-0.764437,-0.125333,0.422422,-0.897692,-0.125333,0.632398,-0.764437,0.125333); -f3(1161,1162,1163,0.469549,0.258137,0.844328,0.299309,0.0768494,0.951057,0.518993,0.133255,0.844328); -f3(1164,1165,1166,0.119441,-0.626133,-0.770513,-0.0400242,-0.636166,-0.770513,0.151595,-0.794687,-0.587785); -f3(1167,1168,1169,-0.0622954,0.990157,-0.125333,0.174223,0.913308,-0.368125,0.185904,0.974542,-0.125333); -f3(1170,1171,1172,0.119441,-0.626133,-0.770513,-0.0267349,-0.424939,-0.904827,-0.0400242,-0.636166,-0.770513); -f3(1173,1174,1175,-0.0622954,0.990157,-0.125333,0.185904,0.974542,-0.125333,-0.0622954,0.990157,0.125333); -f3(1176,1177,1178,0.469549,0.258137,0.844328,0.706067,0.181287,0.684547,0.6388,0.351183,0.684547); -f3(1179,1180,1181,0.271402,0.576758,-0.770513,0.271402,0.328069,-0.904827,0.406309,0.491144,-0.770513); -f3(1182,1183,1184,0.531395,0.499013,0.684547,0.767913,0.422164,0.481754,0.6388,0.599873,0.481754); -f3(1185,1186,1187,0.0194033,0.0597173,-0.998027,0.16558,0.260912,-0.951057,0.0336448,0.0530158,-0.998027); -f3(1188,1189,1190,0.0194033,0.0597173,-0.998027,0.0336448,0.0530158,-0.998027,-0.057904,-0.17821,-0.982287); -f3(1191,1192,1193,0.271402,0.576758,-0.770513,0.406309,0.491144,-0.770513,0.344463,0.73202,-0.587785); -f3(1194,1195,1196,-0.0507986,-0.0369073,-0.998027,-0.287317,-0.113757,-0.951057,-0.0583811,-0.0231147,-0.998027); -f3(1197,1198,1199,0.531395,0.499013,0.684547,0.6388,0.351183,0.684547,0.767913,0.422164,0.481754); -f3(1200,1201,1202,-0.0507986,-0.0369073,-0.998027,-0.0583811,-0.0231147,-0.998027,0.151595,0.11014,-0.982287); -f3(1203,1204,1205,-0.464662,-0.56168,0.684547,-0.589748,-0.428477,0.684547,-0.708947,-0.51508,0.481754); -f3(1206,1207,1208,0.0608178,0.0156154,0.998027,0.309017,0,0.951057,0.299309,0.0768494,0.951057); -f3(1209,1210,1211,-0.72322,-0.091364,-0.684547,-0.869397,0.10983,-0.481754,-0.72322,0.091364,-0.684547); -f3(1212,1213,1214,0.0608178,0.0156154,0.998027,0.0627905,0,0.998027,0.309017,0,0.951057); -f3(1215,1216,1217,-0.464662,-0.56168,0.684547,-0.708947,-0.51508,0.481754,-0.558579,-0.675206,0.481754); -f3(1218,1219,1220,-0.72322,-0.091364,-0.684547,-0.72322,0.091364,-0.684547,-0.531602,-0.0671569,-0.844328); -f3(1221,1222,1223,0.531395,0.499013,-0.684547,0.767913,0.422164,-0.481754,0.6388,0.351183,-0.684547); -f3(1224,1225,1226,0.0608178,-0.0156154,0.998027,0.309017,0,0.951057,0.0627905,0,0.998027); -f3(1227,1228,1229,0.531395,0.499013,-0.684547,0.6388,0.351183,-0.684547,0.390601,0.366799,-0.844328); -f3(1230,1231,1232,0.469549,0.73989,0.481754,0.6388,0.599873,0.481754,0.706067,0.663041,0.24869); -f3(1233,1234,1235,0.0608178,-0.0156154,0.998027,0.299309,-0.0768494,0.951057,0.309017,0,0.951057); -f3(1236,1237,1238,0.0608178,-0.0156154,0.998027,0.0550238,-0.0302496,0.998027,0.270794,-0.14887,0.951057); -f3(1239,1240,1241,0.0608178,-0.0156154,0.998027,0.270794,-0.14887,0.951057,0.299309,-0.0768494,0.951057); -f3(1242,1243,1244,0.469549,0.73989,0.481754,0.706067,0.663041,0.24869,0.518993,0.817802,0.24869); -f3(1245,1246,1247,-0.0583811,-0.0231147,0.998027,-0.0622954,-0.00786974,0.998027,-0.30658,-0.0387301,0.951057); -f3(1248,1249,1250,-0.464662,0.436347,0.770513,-0.228144,0.359497,0.904827,-0.31038,0.291466,0.904827); -f3(1251,1252,1253,0.270794,0.14887,0.951057,0.299309,0.0768494,0.951057,0.469549,0.258137,0.844328); -f3(1254,1255,1256,-0.0583811,-0.0231147,0.998027,-0.30658,-0.0387301,0.951057,-0.287317,-0.113757,0.951057); -f3(1257,1258,1259,-0.464662,0.436347,0.770513,-0.341549,0.538195,0.770513,-0.228144,0.359497,0.904827); -f3(1260,1261,1262,-0.0583811,-0.0231147,0.998027,0.185904,0.0234851,0.982287,-0.0622954,-0.00786974,0.998027); -f3(1263,1264,1265,-0.30658,0.943557,0.125333,-0.0622954,0.990157,-0.125333,-0.0622954,0.990157,0.125333); -f3(1266,1267,1268,0.632398,-0.0798904,0.770513,0.752205,-0.297819,0.587785,0.592662,-0.234651,0.770513); -f3(1269,1270,1271,0.632398,-0.0798904,0.770513,0.592662,-0.234651,0.770513,0.39588,-0.15674,0.904827); -f3(1272,1273,1274,-0.30658,0.943557,0.125333,-0.0622954,0.990157,0.125333,-0.287317,0.88427,0.368125); -f3(1275,1276,1277,0.299309,0.921177,0.24869,0.535827,0.844328,-0,0.309017,0.951057,-0); -f3(1278,1279,1280,0.632398,-0.0798904,0.770513,0.39588,-0.15674,0.904827,0.422422,-0.0533643,0.904827); -f3(1281,1282,1283,0.151595,0.794687,-0.587785,0.271402,0.576758,-0.770513,0.344463,0.73202,-0.587785); -f3(1284,1285,1286,0.299309,0.921177,0.24869,0.309017,0.951057,-0,0.0627905,0.998027,-0); -f3(1287,1288,1289,0.151595,0.794687,-0.587785,0.344463,0.73202,-0.587785,0.39588,0.841287,-0.368125); -f3(1290,1291,1292,0.299309,0.921177,0.24869,0.518993,0.817802,0.24869,0.535827,0.844328,-0); -f3(1293,1294,1295,0.151595,0.794687,-0.587785,0.39588,0.841287,-0.368125,0.174223,0.913308,-0.368125); -f3(1296,1297,1298,0.802638,-0.58315,0.125333,0.632398,-0.764437,-0.125333,0.632398,-0.764437,0.125333); -f3(1299,1300,1301,0.802638,-0.58315,0.125333,0.632398,-0.764437,0.125333,0.752205,-0.546509,0.368125); -f3(1302,1303,1304,0.119441,0.14438,-0.982287,0.344463,0.250267,-0.904827,0.271402,0.328069,-0.904827); -f3(1305,1306,1307,0.344463,-0.73202,-0.587785,0.174223,-0.913308,-0.368125,0.39588,-0.841287,-0.368125); -f3(1308,1309,1310,0.390601,0.366799,0.844328,0.469549,0.258137,0.844328,0.6388,0.351183,0.684547); -f3(1311,1312,1313,0.344463,-0.73202,-0.587785,0.119441,-0.626133,-0.770513,0.151595,-0.794687,-0.587785); -f3(1314,1315,1316,0.119441,0.14438,-0.982287,-0.0507986,-0.0369073,-0.998027,0.151595,0.11014,-0.982287); -f3(1317,1318,1319,0.390601,0.366799,0.844328,0.270794,0.14887,0.951057,0.469549,0.258137,0.844328); -f3(1320,1321,1322,0.390601,0.366799,0.844328,0.6388,0.351183,0.684547,0.531395,0.499013,0.684547); -f3(1323,1324,1325,0.119441,0.14438,-0.982287,0.151595,0.11014,-0.982287,0.344463,0.250267,-0.904827); -f3(1326,1327,1328,0.344463,-0.73202,-0.587785,0.151595,-0.794687,-0.587785,0.174223,-0.913308,-0.368125); -f3(1329,1330,1331,-0.0117658,-0.187012,-0.982287,-0.131573,-0.40494,-0.904827,-0.0267349,-0.424939,-0.904827); -f3(1332,1333,1334,-0.181494,-0.0465998,0.982287,-0.187381,-0,0.982287,0.0627905,0,0.998027); -f3(1335,1336,1337,-0.498199,-0.197251,-0.844328,-0.30658,-0.0387301,-0.951057,-0.287317,-0.113757,-0.951057); -f3(1338,1339,1340,-0.498199,-0.197251,-0.844328,-0.72322,-0.091364,-0.684547,-0.531602,-0.0671569,-0.844328); -f3(1341,1342,1343,-0.498199,-0.197251,-0.844328,-0.531602,-0.0671569,-0.844328,-0.30658,-0.0387301,-0.951057); -f3(1344,1345,1346,-0.960946,0.121396,-0.24869,-0.814769,0.32259,-0.481754,-0.869397,0.10983,-0.481754); -f3(1347,1348,1349,-0.0117658,-0.187012,-0.982287,-0.057904,-0.17821,-0.982287,-0.131573,-0.40494,-0.904827); -f3(1350,1351,1352,-0.0117658,-0.187012,-0.982287,0.0194033,0.0597173,-0.998027,-0.057904,-0.17821,-0.982287); -f3(1353,1354,1355,-0.960946,0.121396,-0.24869,-0.992115,0.125333,0,-0.900566,0.356559,-0.24869); -f3(1356,1357,1358,-0.181494,-0.0465998,0.982287,0.0627905,0,0.998027,0.0608178,0.0156154,0.998027); -f3(1359,1360,1361,-0.960946,0.121396,-0.24869,-0.900566,0.356559,-0.24869,-0.814769,0.32259,-0.481754); -f3(1362,1363,1364,-0.373113,0.205121,0.904827,-0.31038,0.291466,0.904827,-0.164203,0.0902716,0.982287); -f3(1365,1366,1367,-0.373113,-0.792906,0.481754,-0.558579,-0.675206,0.481754,-0.617398,-0.746306,0.24869); -f3(1368,1369,1370,0.390601,0.615489,0.684547,0.531395,0.499013,0.684547,0.6388,0.599873,0.481754); -f3(1371,1372,1373,-0.498199,0.785036,0.368125,-0.287317,0.88427,0.368125,-0.433493,0.683076,0.587785); -f3(1374,1375,1376,0.390601,0.615489,0.684547,0.6388,0.599873,0.481754,0.469549,0.73989,0.481754); -f3(1377,1378,1379,-0.373113,-0.792906,0.481754,-0.617398,-0.746306,0.24869,-0.412403,-0.8764,0.24869); -f3(1380,1381,1382,-0.498199,0.785036,0.368125,-0.30658,0.943557,0.125333,-0.287317,0.88427,0.368125); -f3(1383,1384,1385,0.28711,0.452414,-0.844328,0.225264,0.211537,-0.951057,0.16558,0.260912,-0.951057); -f3(1386,1387,1388,0.0550238,0.0302496,0.998027,0.299309,0.0768494,0.951057,0.270794,0.14887,0.951057); -f3(1389,1390,1391,0.28711,0.452414,-0.844328,0.390601,0.366799,-0.844328,0.225264,0.211537,-0.951057); -f3(1392,1393,1394,0.0550238,0.0302496,0.998027,0.0608178,0.0156154,0.998027,0.299309,0.0768494,0.951057); -f3(1395,1396,1397,-0.0583811,0.927942,-0.368125,0.174223,0.913308,-0.368125,-0.0622954,0.990157,-0.125333); -f3(1398,1399,1400,0.181288,0.385257,-0.904827,0.271402,0.328069,-0.904827,0.271402,0.576758,-0.770513); -f3(1401,1402,1403,-0.25,-0.181636,0.951057,-0.287317,-0.113757,0.951057,-0.433493,-0.314951,0.844328); -f3(1404,1405,1406,0.848776,0.466619,-0.24869,0.848776,0.217929,-0.481754,0.767913,0.422164,-0.481754); -f3(1407,1408,1409,0.848776,0.466619,-0.24869,0.876307,0.481754,-0,0.938153,0.240877,-0.24869); -f3(1410,1411,1412,0.848776,0.466619,-0.24869,0.938153,0.240877,-0.24869,0.848776,0.217929,-0.481754); -f3(1413,1414,1415,-0.25,-0.181636,-0.951057,-0.287317,-0.113757,-0.951057,-0.0507986,-0.0369073,-0.998027); -f3(1416,1417,1418,0.270794,0.833417,0.481754,0.469549,0.73989,0.481754,0.518993,0.817802,0.24869); -f3(1419,1420,1421,0.270794,0.833417,0.481754,0.518993,0.817802,0.24869,0.299309,0.921177,0.24869); -f3(1422,1423,1424,0.422422,0.0533643,0.904827,0.422422,-0.0533643,0.904827,0.185904,0.0234851,0.982287); -f3(1425,1426,1427,0.225264,0.211537,0.951057,0.270794,0.14887,0.951057,0.390601,0.366799,0.844328); -f3(1428,1429,1430,-0.869397,-0.10983,-0.481754,-0.869397,0.10983,-0.481754,-0.72322,-0.091364,-0.684547); -f3(1431,1432,1433,-0.181494,0.0465998,0.982287,0.0550238,-0.0302496,0.998027,0.0608178,-0.0156154,0.998027); -f3(1434,1435,1436,-0.181494,0.0465998,0.982287,0.0627905,0,0.998027,-0.187381,-0,0.982287); -f3(1437,1438,1439,-0.412403,-0.105887,0.904827,-0.187381,-0,0.982287,-0.181494,-0.0465998,0.982287); -f3(1440,1441,1442,0.864484,-0.342274,0.368125,0.802638,-0.58315,0.125333,0.752205,-0.546509,0.368125); -f3(1443,1444,1445,0.864484,-0.342274,0.368125,0.752205,-0.546509,0.368125,0.752205,-0.297819,0.587785); -f3(1446,1447,1448,-0.181494,0.0465998,0.982287,0.0608178,-0.0156154,0.998027,0.0627905,0,0.998027); -f3(1449,1450,1451,-0.412403,-0.105887,0.904827,-0.425779,-0,0.904827,-0.187381,-0,0.982287); -f3(1452,1453,1454,-0.181494,0.0465998,0.982287,-0.164203,0.0902716,0.982287,0.0550238,-0.0302496,0.998027); -f3(1455,1456,1457,-0.589748,0.55381,0.587785,-0.341549,0.538195,0.770513,-0.464662,0.436347,0.770513); -f3(1458,1459,1460,0.0608178,0.966672,0.24869,0.299309,0.921177,0.24869,0.0627905,0.998027,-0); -f3(1461,1462,1463,0.592662,-0.716405,-0.368125,0.39588,-0.841287,-0.368125,0.632398,-0.764437,-0.125333); -f3(1464,1465,1466,-0.589748,0.55381,0.587785,-0.433493,0.683076,0.587785,-0.341549,0.538195,0.770513); -f3(1467,1468,1469,0.0797831,-0.418238,-0.904827,-0.0267349,-0.424939,-0.904827,0.119441,-0.626133,-0.770513); -f3(1470,1471,1472,0.28711,0.452414,0.844328,0.390601,0.366799,0.844328,0.531395,0.499013,0.684547); -f3(1473,1474,1475,-0.30658,0.943557,-0.125333,-0.0583811,0.927942,-0.368125,-0.0622954,0.990157,-0.125333); -f3(1476,1477,1478,0.28711,0.452414,0.844328,0.225264,0.211537,0.951057,0.390601,0.366799,0.844328); -f3(1479,1480,1481,-0.30658,0.943557,-0.125333,-0.0622954,0.990157,-0.125333,-0.30658,0.943557,0.125333); -f3(1482,1483,1484,0.0954915,0.293893,-0.951057,0.16558,0.260912,-0.951057,0.0194033,0.0597173,-0.998027); -f3(1485,1486,1487,0.119441,0.626133,-0.770513,0.271402,0.576758,-0.770513,0.151595,0.794687,-0.587785); -f3(1488,1489,1490,0.28711,0.452414,0.844328,0.531395,0.499013,0.684547,0.390601,0.615489,0.684547); -f3(1491,1492,1493,0.119441,0.626133,-0.770513,0.181288,0.385257,-0.904827,0.271402,0.576758,-0.770513); -f3(1494,1495,1496,-0.181494,-0.951427,0.24869,-0.412403,-0.8764,0.24869,-0.425779,-0.904827,0); -f3(1497,1498,1499,-0.164203,-0.0902716,0.982287,0.0608178,0.0156154,0.998027,0.0550238,0.0302496,0.998027); -f3(1500,1501,1502,-0.164203,-0.0902716,0.982287,-0.181494,-0.0465998,0.982287,0.0608178,0.0156154,0.998027); -f3(1503,1504,1505,-0.181494,-0.951427,0.24869,-0.425779,-0.904827,0,-0.187381,-0.982287,0); -f3(1506,1507,1508,-0.0400242,-0.0483809,-0.998027,-0.0507986,-0.0369073,-0.998027,0.119441,0.14438,-0.982287); -f3(1509,1510,1511,-0.341549,-0.412862,0.844328,-0.433493,-0.314951,0.844328,-0.589748,-0.428477,0.684547); -f3(1512,1513,1514,-0.0400242,-0.0483809,-0.998027,-0.25,-0.181636,-0.951057,-0.0507986,-0.0369073,-0.998027); -f3(1515,1516,1517,-0.677778,-0.268351,-0.684547,-0.869397,-0.10983,-0.481754,-0.72322,-0.091364,-0.684547); -f3(1518,1519,1520,0.225264,0.69329,0.684547,0.390601,0.615489,0.684547,0.469549,0.73989,0.481754); -f3(1521,1522,1523,-0.677778,-0.268351,-0.684547,-0.72322,-0.091364,-0.684547,-0.498199,-0.197251,-0.844328); -f3(1524,1525,1526,-0.341549,-0.412862,0.844328,-0.589748,-0.428477,0.684547,-0.464662,-0.56168,0.684547); -f3(1527,1528,1529,-0.341549,-0.412862,0.844328,-0.25,-0.181636,0.951057,-0.433493,-0.314951,0.844328); -f3(1530,1531,1532,0.225264,0.69329,0.684547,0.469549,0.73989,0.481754,0.270794,0.833417,0.481754); -f3(1533,1534,1535,0.6388,0.599873,-0.481754,0.767913,0.422164,-0.481754,0.531395,0.499013,-0.684547); -f3(1536,1537,1538,-0.558579,0.307081,0.770513,-0.31038,0.291466,0.904827,-0.373113,0.205121,0.904827); -f3(1539,1540,1541,-0.558579,0.307081,0.770513,-0.464662,0.436347,0.770513,-0.31038,0.291466,0.904827); -f3(1542,1543,1544,-0.558579,0.307081,0.770513,-0.589748,0.55381,0.587785,-0.464662,0.436347,0.770513); -f3(1545,1546,1547,-0.531602,0.83767,0.125333,-0.30658,0.943557,0.125333,-0.498199,0.785036,0.368125); -f3(1548,1549,1550,0.174223,0.0689797,0.982287,0.422422,0.0533643,0.904827,0.185904,0.0234851,0.982287); -f3(1551,1552,1553,0.174223,0.0689797,0.982287,0.185904,0.0234851,0.982287,-0.0583811,-0.0231147,0.998027); -f3(1554,1555,1556,0.0457723,0.0429831,0.998027,0.0550238,0.0302496,0.998027,0.270794,0.14887,0.951057); -f3(1557,1558,1559,0.0457723,0.0429831,0.998027,0.270794,0.14887,0.951057,0.225264,0.211537,0.951057); -f3(1560,1561,1562,0.0457723,0.0429831,0.998027,-0.164203,-0.0902716,0.982287,0.0550238,0.0302496,0.998027); -f3(1563,1564,1565,-0.531602,0.83767,0.125333,-0.30658,0.943557,-0.125333,-0.30658,0.943557,0.125333); -f3(1566,1567,1568,-0.0507986,0.807421,-0.587785,0.151595,0.794687,-0.587785,0.174223,0.913308,-0.368125); -f3(1569,1570,1571,-0.0507986,0.807421,-0.587785,0.119441,0.626133,-0.770513,0.151595,0.794687,-0.587785); -f3(1572,1573,1574,-0.617398,-0.158521,0.770513,-0.425779,-0,0.904827,-0.412403,-0.105887,0.904827); -f3(1575,1576,1577,-0.617398,-0.158521,0.770513,-0.637424,-0,0.770513,-0.425779,-0,0.904827); -f3(1578,1579,1580,-0.0507986,0.807421,-0.587785,0.174223,0.913308,-0.368125,-0.0583811,0.927942,-0.368125); -f3(1581,1582,1583,0.802638,-0.101397,0.587785,0.752205,-0.297819,0.587785,0.632398,-0.0798904,0.770513); -f3(1584,1585,1586,0.802638,-0.101397,0.587785,0.864484,-0.342274,0.368125,0.752205,-0.297819,0.587785); -f3(1587,1588,1589,0.0797831,0.169548,-0.982287,0.119441,0.14438,-0.982287,0.271402,0.328069,-0.904827); -f3(1590,1591,1592,0.0797831,0.169548,-0.982287,0.271402,0.328069,-0.904827,0.181288,0.385257,-0.904827); -f3(1593,1594,1595,0.0550238,0.874577,0.481754,0.299309,0.921177,0.24869,0.0608178,0.966672,0.24869); -f3(1596,1597,1598,0.0797831,0.169548,-0.982287,-0.0400242,-0.0483809,-0.998027,0.119441,0.14438,-0.982287); -f3(1599,1600,1601,0.0550238,0.874577,0.481754,0.270794,0.833417,0.481754,0.299309,0.921177,0.24869); -f3(1602,1603,1604,0.802638,-0.58315,-0.125333,0.632398,-0.764437,-0.125333,0.802638,-0.58315,0.125333); -f3(1605,1606,1607,-0.433493,-0.314951,-0.844328,-0.287317,-0.113757,-0.951057,-0.25,-0.181636,-0.951057); -f3(1608,1609,1610,0.802638,-0.58315,-0.125333,0.592662,-0.716405,-0.368125,0.632398,-0.764437,-0.125333); -f3(1611,1612,1613,-0.433493,-0.314951,-0.844328,-0.498199,-0.197251,-0.844328,-0.287317,-0.113757,-0.951057); -f3(1614,1615,1616,-0.433493,-0.314951,-0.844328,-0.677778,-0.268351,-0.684547,-0.498199,-0.197251,-0.844328); -f3(1617,1618,1619,-0.960946,-0.121396,-0.24869,-0.992115,-0.125333,0,-0.992115,0.125333,0); -f3(1620,1621,1622,0.271402,-0.576758,-0.770513,0.119441,-0.626133,-0.770513,0.344463,-0.73202,-0.587785); -f3(1623,1624,1625,0.271402,-0.576758,-0.770513,0.0797831,-0.418238,-0.904827,0.119441,-0.626133,-0.770513); -f3(1626,1627,1628,-0.960946,-0.121396,-0.24869,-0.992115,0.125333,0,-0.960946,0.121396,-0.24869); -f3(1629,1630,1631,-0.960946,-0.121396,-0.24869,-0.960946,0.121396,-0.24869,-0.869397,0.10983,-0.481754); -f3(1632,1633,1634,-0.960946,-0.121396,-0.24869,-0.869397,0.10983,-0.481754,-0.869397,-0.10983,-0.481754); -f3(1635,1636,1637,-0.412403,0.105887,0.904827,-0.164203,0.0902716,0.982287,-0.181494,0.0465998,0.982287); -f3(1638,1639,1640,0.16558,0.260912,0.951057,0.225264,0.211537,0.951057,0.28711,0.452414,0.844328); -f3(1641,1642,1643,-0.412403,0.105887,0.904827,-0.373113,0.205121,0.904827,-0.164203,0.0902716,0.982287); -f3(1644,1645,1646,-0.412403,0.105887,0.904827,-0.187381,-0,0.982287,-0.425779,-0,0.904827); -f3(1647,1648,1649,0.00394265,0.0626666,-0.998027,0.0194033,0.0597173,-0.998027,-0.0117658,-0.187012,-0.982287); -f3(1650,1651,1652,0.00394265,0.0626666,-0.998027,0.0954915,0.293893,-0.951057,0.0194033,0.0597173,-0.998027); -f3(1653,1654,1655,-0.412403,0.105887,0.904827,-0.181494,0.0465998,0.982287,-0.187381,-0,0.982287); -f3(1656,1657,1658,-0.373113,-0.205121,0.904827,-0.181494,-0.0465998,0.982287,-0.164203,-0.0902716,0.982287); -f3(1659,1660,1661,-0.677778,0.636476,0.368125,-0.498199,0.785036,0.368125,-0.433493,0.683076,0.587785); -f3(1662,1663,1664,-0.677778,0.636476,0.368125,-0.433493,0.683076,0.587785,-0.589748,0.55381,0.587785); -f3(1665,1666,1667,-0.373113,-0.205121,0.904827,-0.412403,-0.105887,0.904827,-0.181494,-0.0465998,0.982287); -f3(1668,1669,1670,-0.31038,-0.659591,0.684547,-0.464662,-0.56168,0.684547,-0.558579,-0.675206,0.481754); -f3(1671,1672,1673,-0.677778,0.636476,0.368125,-0.531602,0.83767,0.125333,-0.498199,0.785036,0.368125); -f3(1674,1675,1676,-0.31038,-0.659591,0.684547,-0.558579,-0.675206,0.481754,-0.373113,-0.792906,0.481754); -f3(1677,1678,1679,-0.181494,0.951427,0.24869,0.0608178,0.966672,0.24869,0.0627905,0.998027,-0); -f3(1680,1681,1682,-0.181494,0.951427,0.24869,0.0627905,0.998027,-0,-0.187381,0.982287,0); -f3(1683,1684,1685,0.390601,0.615489,-0.684547,0.531395,0.499013,-0.684547,0.390601,0.366799,-0.844328); -f3(1686,1687,1688,0.16558,0.509602,0.844328,0.28711,0.452414,0.844328,0.390601,0.615489,0.684547); -f3(1689,1690,1691,-0.287317,0.88427,-0.368125,-0.0583811,0.927942,-0.368125,-0.30658,0.943557,-0.125333); -f3(1692,1693,1694,0.390601,0.615489,-0.684547,0.390601,0.366799,-0.844328,0.28711,0.452414,-0.844328); -f3(1695,1696,1697,0.16558,0.509602,0.844328,0.390601,0.615489,0.684547,0.225264,0.69329,0.684547); -f3(1698,1699,1700,0.390601,0.615489,-0.684547,0.6388,0.599873,-0.481754,0.531395,0.499013,-0.684547); -f3(1701,1702,1703,0.0797831,0.418238,-0.904827,0.181288,0.385257,-0.904827,0.119441,0.626133,-0.770513); -f3(1704,1705,1706,0.16558,0.509602,0.844328,0.16558,0.260912,0.951057,0.28711,0.452414,0.844328); -f3(1707,1708,1709,-0.0507986,-0.0369073,0.998027,-0.0583811,-0.0231147,0.998027,-0.287317,-0.113757,0.951057); -f3(1710,1711,1712,-0.0507986,-0.0369073,0.998027,0.174223,0.0689797,0.982287,-0.0583811,-0.0231147,0.998027); -f3(1713,1714,1715,-0.0507986,-0.0369073,0.998027,-0.287317,-0.113757,0.951057,-0.25,-0.181636,0.951057); -f3(1716,1717,1718,-0.136595,-0.128271,0.982287,-0.164203,-0.0902716,0.982287,0.0457723,0.0429831,0.998027); -f3(1719,1720,1721,0.632398,0.0798904,0.770513,0.802638,-0.101397,0.587785,0.632398,-0.0798904,0.770513); -f3(1722,1723,1724,-0.136595,-0.128271,0.982287,-0.373113,-0.205121,0.904827,-0.164203,-0.0902716,0.982287); -f3(1725,1726,1727,-0.196975,-0.238102,-0.951057,-0.25,-0.181636,-0.951057,-0.0400242,-0.0483809,-0.998027); -f3(1728,1729,1730,-0.7836,-0.201194,0.587785,-0.637424,-0,0.770513,-0.617398,-0.158521,0.770513); -f3(1731,1732,1733,0.632398,0.0798904,0.770513,0.632398,-0.0798904,0.770513,0.422422,-0.0533643,0.904827); -f3(1734,1735,1736,0.632398,0.0798904,0.770513,0.422422,-0.0533643,0.904827,0.422422,0.0533643,0.904827); -f3(1737,1738,1739,-0.814769,-0.32259,-0.481754,-0.869397,-0.10983,-0.481754,-0.677778,-0.268351,-0.684547); -f3(1740,1741,1742,-0.7836,-0.201194,0.587785,-0.809017,-0,0.587785,-0.637424,-0,0.770513); -f3(1743,1744,1745,0.922445,-0.365222,0.125333,0.802638,-0.58315,0.125333,0.864484,-0.342274,0.368125); -f3(1746,1747,1748,-0.708947,0.389747,0.587785,-0.677778,0.636476,0.368125,-0.589748,0.55381,0.587785); -f3(1749,1750,1751,-0.708947,0.389747,0.587785,-0.589748,0.55381,0.587785,-0.558579,0.307081,0.770513); -f3(1752,1753,1754,-0.531602,0.83767,-0.125333,-0.287317,0.88427,-0.368125,-0.30658,0.943557,-0.125333); -f3(1755,1756,1757,0.0457723,0.72753,0.684547,0.225264,0.69329,0.684547,0.270794,0.833417,0.481754); -f3(1758,1759,1760,0.922445,-0.365222,0.125333,0.802638,-0.58315,-0.125333,0.802638,-0.58315,0.125333); -f3(1761,1762,1763,0.0457723,0.72753,0.684547,0.270794,0.833417,0.481754,0.0550238,0.874577,0.481754); -f3(1764,1765,1766,0.515687,-0.623358,-0.587785,0.271402,-0.576758,-0.770513,0.344463,-0.73202,-0.587785); -f3(1767,1768,1769,-0.531602,0.83767,-0.125333,-0.30658,0.943557,-0.125333,-0.531602,0.83767,0.125333); -f3(1770,1771,1772,0.515687,-0.623358,-0.587785,0.344463,-0.73202,-0.587785,0.39588,-0.841287,-0.368125); -f3(1773,1774,1775,0.515687,-0.623358,-0.587785,0.39588,-0.841287,-0.368125,0.592662,-0.716405,-0.368125); -f3(1776,1777,1778,-0.0400242,0.636166,-0.770513,0.0797831,0.418238,-0.904827,0.119441,0.626133,-0.770513); -f3(1779,1780,1781,0.0336448,0.0530158,0.998027,0.0457723,0.0429831,0.998027,0.225264,0.211537,0.951057); -f3(1782,1783,1784,0.0351118,-0.184062,-0.982287,-0.0267349,-0.424939,-0.904827,0.0797831,-0.418238,-0.904827); -f3(1785,1786,1787,0.0351118,-0.184062,-0.982287,0.00394265,0.0626666,-0.998027,-0.0117658,-0.187012,-0.982287); -f3(1788,1789,1790,-0.0400242,0.636166,-0.770513,0.119441,0.626133,-0.770513,-0.0507986,0.807421,-0.587785); -f3(1791,1792,1793,0.0351118,-0.184062,-0.982287,-0.0117658,-0.187012,-0.982287,-0.0267349,-0.424939,-0.904827); -f3(1794,1795,1796,-0.0267349,-0.0568146,-0.998027,-0.196975,-0.238102,-0.951057,-0.0400242,-0.0483809,-0.998027); -f3(1797,1798,1799,0.0336448,0.0530158,0.998027,0.225264,0.211537,0.951057,0.16558,0.260912,0.951057); -f3(1800,1801,1802,-0.164203,-0.860785,0.481754,-0.373113,-0.792906,0.481754,-0.412403,-0.8764,0.24869); -f3(1803,1804,1805,-0.0267349,-0.0568146,-0.998027,-0.0400242,-0.0483809,-0.998027,0.0797831,0.169548,-0.982287); -f3(1806,1807,1808,-0.589748,-0.428477,-0.684547,-0.677778,-0.268351,-0.684547,-0.433493,-0.314951,-0.844328); -f3(1809,1810,1811,-0.164203,-0.860785,0.481754,-0.412403,-0.8764,0.24869,-0.181494,-0.951427,0.24869); -f3(1812,1813,1814,-0.558579,-0.307081,0.770513,-0.412403,-0.105887,0.904827,-0.373113,-0.205121,0.904827); -f3(1815,1816,1817,-0.589748,-0.428477,-0.684547,-0.814769,-0.32259,-0.481754,-0.677778,-0.268351,-0.684547); -f3(1818,1819,1820,-0.558579,-0.307081,0.770513,-0.617398,-0.158521,0.770513,-0.412403,-0.105887,0.904827); -f3(1821,1822,1823,-0.617398,0.158521,0.770513,-0.412403,0.105887,0.904827,-0.425779,-0,0.904827); -f3(1824,1825,1826,-0.617398,0.158521,0.770513,-0.425779,-0,0.904827,-0.637424,-0,0.770513); -f3(1827,1828,1829,0.16558,0.509602,-0.844328,0.390601,0.615489,-0.684547,0.28711,0.452414,-0.844328); -f3(1830,1831,1832,-0.164203,0.860785,0.481754,0.0550238,0.874577,0.481754,0.0608178,0.966672,0.24869); -f3(1833,1834,1835,0.16558,0.509602,-0.844328,0.16558,0.260912,-0.951057,0.0954915,0.293893,-0.951057); -f3(1836,1837,1838,-0.164203,0.860785,0.481754,0.0608178,0.966672,0.24869,-0.181494,0.951427,0.24869); -f3(1839,1840,1841,0.16558,0.509602,-0.844328,0.28711,0.452414,-0.844328,0.16558,0.260912,-0.951057); -f3(1842,1843,1844,-0.617398,0.158521,0.770513,-0.373113,0.205121,0.904827,-0.412403,0.105887,0.904827); -f3(1845,1846,1847,-0.617398,0.158521,0.770513,-0.558579,0.307081,0.770513,-0.373113,0.205121,0.904827); -f3(1848,1849,1850,-0.72322,0.679149,0.125333,-0.531602,0.83767,0.125333,-0.677778,0.636476,0.368125); -f3(1851,1852,1853,-0.196975,-0.238102,0.951057,-0.25,-0.181636,0.951057,-0.341549,-0.412862,0.844328); -f3(1854,1855,1856,-0.25,0.769421,-0.587785,-0.0583811,0.927942,-0.368125,-0.287317,0.88427,-0.368125); -f3(1857,1858,1859,-0.25,0.769421,-0.587785,-0.0400242,0.636166,-0.770513,-0.0507986,0.807421,-0.587785); -f3(1860,1861,1862,0.706067,0.663041,-0.24869,0.728969,0.684547,-0,0.876307,0.481754,-0); -f3(1863,1864,1865,0.706067,0.663041,-0.24869,0.535827,0.844328,-0,0.728969,0.684547,-0); -f3(1866,1867,1868,0.706067,0.663041,-0.24869,0.876307,0.481754,-0,0.848776,0.466619,-0.24869); -f3(1869,1870,1871,0.706067,0.663041,-0.24869,0.848776,0.466619,-0.24869,0.767913,0.422164,-0.481754); -f3(1872,1873,1874,0.0954915,0.293893,0.951057,0.16558,0.260912,0.951057,0.16558,0.509602,0.844328); -f3(1875,1876,1877,0.706067,0.663041,-0.24869,0.767913,0.422164,-0.481754,0.6388,0.599873,-0.481754); -f3(1878,1879,1880,-0.31038,-0.291466,0.904827,-0.373113,-0.205121,0.904827,-0.136595,-0.128271,0.982287); -f3(1881,1882,1883,-0.25,0.769421,-0.587785,-0.0507986,0.807421,-0.587785,-0.0583811,0.927942,-0.368125); -f3(1884,1885,1886,0.0351118,0.184062,-0.982287,0.181288,0.385257,-0.904827,0.0797831,0.418238,-0.904827); -f3(1887,1888,1889,0.0351118,0.184062,-0.982287,-0.0267349,-0.0568146,-0.998027,0.0797831,0.169548,-0.982287); -f3(1890,1891,1892,0.0351118,0.184062,-0.982287,0.0797831,0.169548,-0.982287,0.181288,0.385257,-0.904827); -f3(1893,1894,1895,0.39588,0.15674,0.904827,0.422422,0.0533643,0.904827,0.174223,0.0689797,0.982287); -f3(1896,1897,1898,-0.341549,-0.412862,-0.844328,-0.589748,-0.428477,-0.684547,-0.433493,-0.314951,-0.844328); -f3(1899,1900,1901,-0.341549,-0.412862,-0.844328,-0.25,-0.181636,-0.951057,-0.196975,-0.238102,-0.951057); -f3(1902,1903,1904,-0.900566,-0.231226,0.368125,-0.809017,-0,0.587785,-0.7836,-0.201194,0.587785); -f3(1905,1906,1907,0.922445,-0.116532,0.368125,0.922445,-0.365222,0.125333,0.864484,-0.342274,0.368125); -f3(1908,1909,1910,-0.900566,-0.231226,0.368125,-0.929776,-0,0.368125,-0.809017,-0,0.587785); -f3(1911,1912,1913,-0.341549,-0.412862,-0.844328,-0.433493,-0.314951,-0.844328,-0.25,-0.181636,-0.951057); -f3(1914,1915,1916,-0.900566,-0.231226,0.368125,-0.992115,-0,0.125333,-0.929776,-0,0.368125); -f3(1917,1918,1919,0.922445,-0.116532,0.368125,0.864484,-0.342274,0.368125,0.802638,-0.101397,0.587785); -f3(1920,1921,1922,-0.900566,-0.356559,-0.24869,-0.960946,-0.121396,-0.24869,-0.869397,-0.10983,-0.481754); -f3(1923,1924,1925,-0.900566,-0.356559,-0.24869,-0.929776,-0.368125,0,-0.992115,-0.125333,0); -f3(1926,1927,1928,-0.900566,-0.356559,-0.24869,-0.809017,-0.587785,0,-0.929776,-0.368125,0); -f3(1929,1930,1931,-0.900566,-0.356559,-0.24869,-0.869397,-0.10983,-0.481754,-0.814769,-0.32259,-0.481754); -f3(1932,1933,1934,-0.412403,0.8764,0.24869,-0.181494,0.951427,0.24869,-0.187381,0.982287,0); -f3(1935,1936,1937,-0.900566,-0.356559,-0.24869,-0.992115,-0.125333,0,-0.960946,-0.121396,-0.24869); -f3(1938,1939,1940,-0.412403,0.8764,0.24869,-0.187381,0.982287,0,-0.425779,0.904827,0); -f3(1941,1942,1943,-0.814769,0.447923,0.368125,-0.677778,0.636476,0.368125,-0.708947,0.389747,0.587785); -f3(1944,1945,1946,0.752205,-0.546509,-0.368125,0.592662,-0.716405,-0.368125,0.802638,-0.58315,-0.125333); -f3(1947,1948,1949,-0.814769,0.447923,0.368125,-0.72322,0.679149,0.125333,-0.677778,0.636476,0.368125); -f3(1950,1951,1952,0.0336448,0.534769,0.844328,0.0954915,0.293893,0.951057,0.16558,0.509602,0.844328); -f3(1953,1954,1955,0.181288,-0.385257,-0.904827,0.0797831,-0.418238,-0.904827,0.271402,-0.576758,-0.770513); -f3(1956,1957,1958,0.0336448,0.534769,0.844328,0.225264,0.69329,0.684547,0.0457723,0.72753,0.684547); -f3(1959,1960,1961,0.0336448,0.534769,0.844328,0.16558,0.509602,0.844328,0.225264,0.69329,0.684547); -f3(1962,1963,1964,-0.498199,0.785036,-0.368125,-0.287317,0.88427,-0.368125,-0.531602,0.83767,-0.125333); -f3(1965,1966,1967,0.0608178,-0.966672,0.24869,-0.187381,-0.982287,0,0.0627905,-0.998027,0); -f3(1968,1969,1970,0.0608178,-0.966672,0.24869,-0.181494,-0.951427,0.24869,-0.187381,-0.982287,0); -f3(1971,1972,1973,0.0194033,0.308407,-0.951057,0.0954915,0.293893,-0.951057,0.00394265,0.0626666,-0.998027); -f3(1974,1975,1976,-0.0267349,0.424939,-0.904827,0.0797831,0.418238,-0.904827,-0.0400242,0.636166,-0.770513); -f3(1977,1978,1979,-0.100404,-0.158211,0.982287,-0.136595,-0.128271,0.982287,0.0457723,0.0429831,0.998027); -f3(1980,1981,1982,-0.100404,-0.158211,0.982287,0.0457723,0.0429831,0.998027,0.0336448,0.0530158,0.998027); -f3(1983,1984,1985,-0.228144,-0.484831,0.844328,-0.341549,-0.412862,0.844328,-0.464662,-0.56168,0.684547); -f3(1986,1987,1988,-0.131573,-0.279607,-0.951057,-0.196975,-0.238102,-0.951057,-0.0267349,-0.0568146,-0.998027); -f3(1989,1990,1991,-0.708947,-0.389747,0.587785,-0.617398,-0.158521,0.770513,-0.558579,-0.307081,0.770513); -f3(1992,1993,1994,-0.708947,-0.51508,-0.481754,-0.814769,-0.32259,-0.481754,-0.589748,-0.428477,-0.684547); -f3(1995,1996,1997,-0.228144,-0.484831,0.844328,-0.464662,-0.56168,0.684547,-0.31038,-0.659591,0.684547); -f3(1998,1999,2000,-0.708947,-0.389747,0.587785,-0.7836,-0.201194,0.587785,-0.617398,-0.158521,0.770513); -f3(2001,2002,2003,-0.228144,-0.484831,0.844328,-0.196975,-0.238102,0.951057,-0.341549,-0.412862,0.844328); -f3(2004,2005,2006,-0.136595,0.716057,0.684547,0.0550238,0.874577,0.481754,-0.164203,0.860785,0.481754); -f3(2007,2008,2009,-0.7836,0.201194,0.587785,-0.617398,0.158521,0.770513,-0.637424,-0,0.770513); -f3(2010,2011,2012,0.469549,0.73989,-0.481754,0.6388,0.599873,-0.481754,0.390601,0.615489,-0.684547); -f3(2013,2014,2015,-0.7836,0.201194,0.587785,-0.637424,-0,0.770513,-0.809017,-0,0.587785); -f3(2016,2017,2018,-0.7836,0.201194,0.587785,-0.558579,0.307081,0.770513,-0.617398,0.158521,0.770513); -f3(2019,2020,2021,-0.7836,0.201194,0.587785,-0.708947,0.389747,0.587785,-0.558579,0.307081,0.770513); -f3(2022,2023,2024,-0.136595,0.716057,0.684547,0.0457723,0.72753,0.684547,0.0550238,0.874577,0.481754); -f3(2025,2026,2027,0.151595,0.11014,0.982287,0.39588,0.15674,0.904827,0.174223,0.0689797,0.982287); -f3(2028,2029,2030,0.151595,0.11014,0.982287,0.174223,0.0689797,0.982287,-0.0507986,-0.0369073,0.998027); -f3(2031,2032,2033,0.0194033,0.0597173,0.998027,0.16558,0.260912,0.951057,0.0954915,0.293893,0.951057); -f3(2034,2035,2036,0.0194033,0.0597173,0.998027,0.0336448,0.0530158,0.998027,0.16558,0.260912,0.951057); -f3(2037,2038,2039,-0.72322,0.679149,-0.125333,-0.531602,0.83767,-0.125333,-0.531602,0.83767,0.125333); -f3(2040,2041,2042,-0.72322,0.679149,-0.125333,-0.531602,0.83767,0.125333,-0.72322,0.679149,0.125333); -f3(2043,2044,2045,0.0194033,0.0597173,0.998027,-0.100404,-0.158211,0.982287,0.0336448,0.0530158,0.998027); -f3(2046,2047,2048,0.802638,0.101397,0.587785,0.922445,-0.116532,0.368125,0.802638,-0.101397,0.587785); -f3(2049,2050,2051,-0.196975,0.606226,-0.770513,-0.0267349,0.424939,-0.904827,-0.0400242,0.636166,-0.770513); -f3(2052,2053,2054,0.802638,0.101397,0.587785,0.802638,-0.101397,0.587785,0.632398,0.0798904,0.770513); -f3(2055,2056,2057,-0.196975,0.606226,-0.770513,-0.0400242,0.636166,-0.770513,-0.25,0.769421,-0.587785); -f3(2058,2059,2060,-0.464662,-0.436347,0.770513,-0.708947,-0.389747,0.587785,-0.558579,-0.307081,0.770513); -f3(2061,2062,2063,-0.464662,-0.436347,0.770513,-0.373113,-0.205121,0.904827,-0.31038,-0.291466,0.904827); -f3(2064,2065,2066,-0.0117658,-0.0616783,-0.998027,-0.0267349,-0.0568146,-0.998027,0.0351118,0.184062,-0.982287); -f3(2067,2068,2069,0.922445,-0.365222,-0.125333,0.802638,-0.58315,-0.125333,0.922445,-0.365222,0.125333); -f3(2070,2071,2072,-0.464662,-0.436347,0.770513,-0.558579,-0.307081,0.770513,-0.373113,-0.205121,0.904827); -f3(2073,2074,2075,0.922445,-0.365222,-0.125333,0.752205,-0.546509,-0.368125,0.802638,-0.58315,-0.125333); -f3(2076,2077,2078,-0.0117658,-0.0616783,-0.998027,-0.131573,-0.279607,-0.951057,-0.0267349,-0.0568146,-0.998027); -f3(2079,2080,2081,0.406309,-0.491144,-0.770513,0.271402,-0.576758,-0.770513,0.515687,-0.623358,-0.587785); -f3(2082,2083,2084,-0.960946,-0.246729,0.125333,-0.992115,-0,0.125333,-0.900566,-0.231226,0.368125); -f3(2085,2086,2087,-0.464662,-0.56168,-0.684547,-0.589748,-0.428477,-0.684547,-0.341549,-0.412862,-0.844328); -f3(2088,2089,2090,-0.464662,-0.56168,-0.684547,-0.708947,-0.51508,-0.481754,-0.589748,-0.428477,-0.684547); -f3(2091,2092,2093,0.406309,-0.491144,-0.770513,0.181288,-0.385257,-0.904827,0.271402,-0.576758,-0.770513); -f3(2094,2095,2096,-0.373113,0.792906,0.481754,-0.181494,0.951427,0.24869,-0.412403,0.8764,0.24869); -f3(2097,2098,2099,-0.869397,0.477955,0.125333,-0.72322,0.679149,0.125333,-0.814769,0.447923,0.368125); -f3(2100,2101,2102,-0.869397,0.477955,0.125333,-0.72322,0.679149,-0.125333,-0.72322,0.679149,0.125333); -f3(2103,2104,2105,-0.0117658,0.0616783,-0.998027,0.00394265,0.0626666,-0.998027,0.0351118,-0.184062,-0.982287); -f3(2106,2107,2108,-0.433493,0.683076,-0.587785,-0.25,0.769421,-0.587785,-0.287317,0.88427,-0.368125); -f3(2109,2110,2111,-0.373113,0.792906,0.481754,-0.164203,0.860785,0.481754,-0.181494,0.951427,0.24869); -f3(2112,2113,2114,-0.0117658,0.0616783,-0.998027,0.0194033,0.308407,-0.951057,0.00394265,0.0626666,-0.998027); -f3(2115,2116,2117,-0.433493,0.683076,-0.587785,-0.287317,0.88427,-0.368125,-0.498199,0.785036,-0.368125); -f3(2118,2119,2120,-0.433493,0.683076,-0.587785,-0.196975,0.606226,-0.770513,-0.25,0.769421,-0.587785); -f3(2121,2122,2123,-0.136595,-0.716057,0.684547,-0.31038,-0.659591,0.684547,-0.373113,-0.792906,0.481754); -f3(2124,2125,2126,-0.136595,-0.716057,0.684547,-0.373113,-0.792906,0.481754,-0.164203,-0.860785,0.481754); -f3(2127,2128,2129,-0.0117658,0.187012,-0.982287,0.0797831,0.418238,-0.904827,-0.0267349,0.424939,-0.904827); -f3(2130,2131,2132,-0.0117658,0.187012,-0.982287,0.0351118,0.184062,-0.982287,0.0797831,0.418238,-0.904827); -f3(2133,2134,2135,0.0194033,0.308407,0.951057,0.0954915,0.293893,0.951057,0.0336448,0.534769,0.844328); -f3(2136,2137,2138,0.225264,0.69329,-0.684547,0.390601,0.615489,-0.684547,0.16558,0.509602,-0.844328); -f3(2139,2140,2141,-0.0117658,0.187012,-0.982287,-0.0117658,-0.0616783,-0.998027,0.0351118,0.184062,-0.982287); -f3(2142,2143,2144,0.225264,0.69329,-0.684547,0.469549,0.73989,-0.481754,0.390601,0.615489,-0.684547); -f3(2145,2146,2147,-0.228144,-0.484831,-0.844328,-0.196975,-0.238102,-0.951057,-0.131573,-0.279607,-0.951057); -f3(2148,2149,2150,-0.228144,-0.359497,0.904827,-0.136595,-0.128271,0.982287,-0.100404,-0.158211,0.982287); -f3(2151,2152,2153,-0.228144,-0.484831,-0.844328,-0.464662,-0.56168,-0.684547,-0.341549,-0.412862,-0.844328); -f3(2154,2155,2156,-0.228144,-0.484831,-0.844328,-0.341549,-0.412862,-0.844328,-0.196975,-0.238102,-0.951057); -f3(2157,2158,2159,-0.228144,-0.359497,0.904827,-0.31038,-0.291466,0.904827,-0.136595,-0.128271,0.982287); -f3(2160,2161,2162,-0.0400242,-0.0483809,0.998027,0.151595,0.11014,0.982287,-0.0507986,-0.0369073,0.998027); -f3(2163,2164,2165,-0.814769,-0.447923,0.368125,-0.900566,-0.231226,0.368125,-0.7836,-0.201194,0.587785); -f3(2166,2167,2168,-0.7836,-0.569319,-0.24869,-0.809017,-0.587785,0,-0.900566,-0.356559,-0.24869); -f3(2169,2170,2171,-0.7836,-0.569319,-0.24869,-0.900566,-0.356559,-0.24869,-0.814769,-0.32259,-0.481754); -f3(2172,2173,2174,-0.0400242,-0.0483809,0.998027,-0.25,-0.181636,0.951057,-0.196975,-0.238102,0.951057); -f3(2175,2176,2177,-0.7836,-0.569319,-0.24869,-0.814769,-0.32259,-0.481754,-0.708947,-0.51508,-0.481754); -f3(2178,2179,2180,-0.900566,0.231226,0.368125,-0.809017,-0,0.587785,-0.929776,-0,0.368125); -f3(2181,2182,2183,-0.0400242,-0.0483809,0.998027,-0.0507986,-0.0369073,0.998027,-0.25,-0.181636,0.951057); -f3(2184,2185,2186,-0.900566,0.231226,0.368125,-0.7836,0.201194,0.587785,-0.809017,-0,0.587785); -f3(2187,2188,2189,-0.814769,-0.447923,0.368125,-0.7836,-0.201194,0.587785,-0.708947,-0.389747,0.587785); -f3(2190,2191,2192,0.592662,0.234651,0.770513,0.632398,0.0798904,0.770513,0.422422,0.0533643,0.904827); -f3(2193,2194,2195,-0.900566,0.231226,0.368125,-0.929776,-0,0.368125,-0.992115,-0,0.125333); -f3(2196,2197,2198,-0.814769,-0.447923,0.368125,-0.960946,-0.246729,0.125333,-0.900566,-0.231226,0.368125); -f3(2199,2200,2201,-0.900566,0.231226,0.368125,-0.814769,0.447923,0.368125,-0.708947,0.389747,0.587785); -f3(2202,2203,2204,0.592662,0.234651,0.770513,0.422422,0.0533643,0.904827,0.39588,0.15674,0.904827); -f3(2205,2206,2207,-0.900566,0.231226,0.368125,-0.708947,0.389747,0.587785,-0.7836,0.201194,0.587785); -f3(2208,2209,2210,-0.900566,0.231226,0.368125,-0.869397,0.477955,0.125333,-0.814769,0.447923,0.368125); -f3(2211,2212,2213,-0.617398,0.746306,0.24869,-0.412403,0.8764,0.24869,-0.425779,0.904827,0); -f3(2214,2215,2216,-0.617398,0.746306,0.24869,-0.425779,0.904827,0,-0.637424,0.770513,0); -f3(2217,2218,2219,-0.677778,0.636476,-0.368125,-0.531602,0.83767,-0.125333,-0.72322,0.679149,-0.125333); -f3(2220,2221,2222,0.592662,0.234651,0.770513,0.802638,0.101397,0.587785,0.632398,0.0798904,0.770513); -f3(2223,2224,2225,-0.677778,0.636476,-0.368125,-0.498199,0.785036,-0.368125,-0.531602,0.83767,-0.125333); -f3(2226,2227,2228,-0.100404,0.526336,0.844328,0.0457723,0.72753,0.684547,-0.136595,0.716057,0.684547); -f3(2229,2230,2231,-0.100404,0.526336,0.844328,0.0194033,0.308407,0.951057,0.0336448,0.534769,0.844328); -f3(2232,2233,2234,-0.100404,0.526336,0.844328,0.0336448,0.534769,0.844328,0.0457723,0.72753,0.684547); -f3(2235,2236,2237,0.984292,-0.124345,0.125333,0.922445,-0.365222,0.125333,0.922445,-0.116532,0.368125); -f3(2238,2239,2240,0.984292,-0.124345,0.125333,0.922445,-0.365222,-0.125333,0.922445,-0.365222,0.125333); -f3(2241,2242,2243,-0.131573,0.40494,-0.904827,-0.0267349,0.424939,-0.904827,-0.196975,0.606226,-0.770513); -f3(2244,2245,2246,0.654508,-0.475528,-0.587785,0.515687,-0.623358,-0.587785,0.592662,-0.716405,-0.368125); -f3(2247,2248,2249,0.654508,-0.475528,-0.587785,0.592662,-0.716405,-0.368125,0.752205,-0.546509,-0.368125); -f3(2250,2251,2252,-0.057904,-0.303543,-0.951057,-0.131573,-0.279607,-0.951057,-0.0117658,-0.0616783,-0.998027); -f3(2253,2254,2255,-0.057904,-0.17821,0.982287,-0.100404,-0.158211,0.982287,0.0194033,0.0597173,0.998027); -f3(2256,2257,2258,0.654508,-0.475528,-0.587785,0.406309,-0.491144,-0.770513,0.515687,-0.623358,-0.587785); -f3(2259,2260,2261,-0.057904,-0.17821,0.982287,-0.228144,-0.359497,0.904827,-0.100404,-0.158211,0.982287); -f3(2262,2263,2264,-0.558579,-0.675206,-0.481754,-0.708947,-0.51508,-0.481754,-0.464662,-0.56168,-0.684547); -f3(2265,2266,2267,-0.589748,-0.55381,0.587785,-0.708947,-0.389747,0.587785,-0.464662,-0.436347,0.770513); -f3(2268,2269,2270,0.0797831,-0.169548,-0.982287,0.0797831,-0.418238,-0.904827,0.181288,-0.385257,-0.904827); -f3(2271,2272,2273,0.0797831,-0.169548,-0.982287,-0.0117658,0.0616783,-0.998027,0.0351118,-0.184062,-0.982287); -f3(2274,2275,2276,0.0797831,-0.169548,-0.982287,0.0351118,-0.184062,-0.982287,0.0797831,-0.418238,-0.904827); -f3(2277,2278,2279,-0.589748,-0.55381,0.587785,-0.814769,-0.447923,0.368125,-0.708947,-0.389747,0.587785); -f3(2280,2281,2282,0.0550238,-0.874577,0.481754,-0.164203,-0.860785,0.481754,-0.181494,-0.951427,0.24869); -f3(2283,2284,2285,-0.869397,0.477955,-0.125333,-0.677778,0.636476,-0.368125,-0.72322,0.679149,-0.125333); -f3(2286,2287,2288,-0.869397,0.477955,-0.125333,-0.72322,0.679149,-0.125333,-0.869397,0.477955,0.125333); -f3(2289,2290,2291,-0.960946,-0.246729,-0.125333,-0.992115,-0,0.125333,-0.960946,-0.246729,0.125333); -f3(2292,2293,2294,-0.341549,0.538195,-0.770513,-0.131573,0.40494,-0.904827,-0.196975,0.606226,-0.770513); -f3(2295,2296,2297,0.0550238,-0.874577,0.481754,-0.181494,-0.951427,0.24869,0.0608178,-0.966672,0.24869); -f3(2298,2299,2300,-0.960946,-0.246729,-0.125333,-0.992115,0,-0.125333,-0.992115,-0,0.125333); -f3(2301,2302,2303,0.0336448,0.534769,-0.844328,0.16558,0.509602,-0.844328,0.0954915,0.293893,-0.951057); -f3(2304,2305,2306,0.0336448,0.534769,-0.844328,0.0954915,0.293893,-0.951057,0.0194033,0.308407,-0.951057); -f3(2307,2308,2309,-0.341549,0.538195,-0.770513,-0.196975,0.606226,-0.770513,-0.433493,0.683076,-0.587785); -f3(2310,2311,2312,-0.31038,0.659591,0.684547,-0.164203,0.860785,0.481754,-0.373113,0.792906,0.481754); -f3(2313,2314,2315,0.0336448,0.534769,-0.844328,0.225264,0.69329,-0.684547,0.16558,0.509602,-0.844328); -f3(2316,2317,2318,0.00394265,-0.0626666,-0.998027,-0.0117658,-0.0616783,-0.998027,-0.0117658,0.187012,-0.982287); -f3(2319,2320,2321,0.00394265,-0.0626666,-0.998027,-0.057904,-0.303543,-0.951057,-0.0117658,-0.0616783,-0.998027); -f3(2322,2323,2324,-0.31038,0.659591,0.684547,-0.136595,0.716057,0.684547,-0.164203,0.860785,0.481754); -f3(2325,2326,2327,-0.31038,-0.659591,-0.684547,-0.558579,-0.675206,-0.481754,-0.464662,-0.56168,-0.684547); -f3(2328,2329,2330,-0.131573,-0.279607,0.951057,-0.196975,-0.238102,0.951057,-0.228144,-0.484831,0.844328); -f3(2331,2332,2333,0.00394265,0.0626666,0.998027,0.0194033,0.0597173,0.998027,0.0954915,0.293893,0.951057); -f3(2334,2335,2336,-0.31038,-0.659591,-0.684547,-0.464662,-0.56168,-0.684547,-0.228144,-0.484831,-0.844328); -f3(2337,2338,2339,0.518993,0.817802,-0.24869,0.535827,0.844328,-0,0.706067,0.663041,-0.24869); -f3(2340,2341,2342,-0.960946,0.246729,0.125333,-0.869397,0.477955,0.125333,-0.900566,0.231226,0.368125); -f3(2343,2344,2345,0.518993,0.817802,-0.24869,0.706067,0.663041,-0.24869,0.6388,0.599873,-0.481754); -f3(2346,2347,2348,-0.960946,0.246729,0.125333,-0.900566,0.231226,0.368125,-0.992115,-0,0.125333); -f3(2349,2350,2351,0.518993,0.817802,-0.24869,0.6388,0.599873,-0.481754,0.469549,0.73989,-0.481754); -f3(2352,2353,2354,0.00394265,0.0626666,0.998027,0.0954915,0.293893,0.951057,0.0194033,0.308407,0.951057); -f3(2355,2356,2357,0.00394265,0.0626666,0.998027,-0.057904,-0.17821,0.982287,0.0194033,0.0597173,0.998027); -f3(2358,2359,2360,-0.589748,0.55381,-0.587785,-0.498199,0.785036,-0.368125,-0.677778,0.636476,-0.368125); -f3(2361,2362,2363,0.344463,0.250267,0.904827,0.39588,0.15674,0.904827,0.151595,0.11014,0.982287); -f3(2364,2365,2366,-0.341549,-0.538195,0.770513,-0.31038,-0.291466,0.904827,-0.228144,-0.359497,0.904827); -f3(2367,2368,2369,-0.341549,-0.538195,0.770513,-0.464662,-0.436347,0.770513,-0.31038,-0.291466,0.904827); -f3(2370,2371,2372,-0.589748,0.55381,-0.587785,-0.433493,0.683076,-0.587785,-0.498199,0.785036,-0.368125); -f3(2373,2374,2375,-0.057904,0.17821,-0.982287,0.00394265,-0.0626666,-0.998027,-0.0117658,0.187012,-0.982287); -f3(2376,2377,2378,-0.057904,0.17821,-0.982287,-0.0117658,0.187012,-0.982287,-0.0267349,0.424939,-0.904827); -f3(2379,2380,2381,0.922445,0.116532,0.368125,0.922445,-0.116532,0.368125,0.802638,0.101397,0.587785); -f3(2382,2383,2384,-0.057904,0.17821,-0.982287,-0.0267349,0.424939,-0.904827,-0.131573,0.40494,-0.904827); -f3(2385,2386,2387,-0.869397,-0.477955,0.125333,-0.960946,-0.246729,0.125333,-0.814769,-0.447923,0.368125); -f3(2388,2389,2390,0.922445,0.116532,0.368125,0.984292,-0.124345,0.125333,0.922445,-0.116532,0.368125); -f3(2391,2392,2393,-0.100404,-0.526336,-0.844328,-0.131573,-0.279607,-0.951057,-0.057904,-0.303543,-0.951057); -f3(2394,2395,2396,-0.100404,-0.526336,-0.844328,-0.31038,-0.659591,-0.684547,-0.228144,-0.484831,-0.844328); -f3(2397,2398,2399,0.864484,-0.342274,-0.368125,0.752205,-0.546509,-0.368125,0.922445,-0.365222,-0.125333); -f3(2400,2401,2402,-0.558579,0.675206,0.481754,-0.373113,0.792906,0.481754,-0.412403,0.8764,0.24869); -f3(2403,2404,2405,-0.558579,0.675206,0.481754,-0.412403,0.8764,0.24869,-0.617398,0.746306,0.24869); -f3(2406,2407,2408,-0.100404,-0.526336,-0.844328,-0.228144,-0.484831,-0.844328,-0.131573,-0.279607,-0.951057); -f3(2409,2410,2411,-0.617398,-0.746306,-0.24869,-0.637424,-0.770513,0,-0.809017,-0.587785,0); -f3(2412,2413,2414,-0.617398,-0.746306,-0.24869,-0.809017,-0.587785,0,-0.7836,-0.569319,-0.24869); -f3(2415,2416,2417,-0.617398,-0.746306,-0.24869,-0.708947,-0.51508,-0.481754,-0.558579,-0.675206,-0.481754); -f3(2418,2419,2420,0.271402,-0.328069,-0.904827,0.181288,-0.385257,-0.904827,0.406309,-0.491144,-0.770513); -f3(2421,2422,2423,-0.617398,-0.746306,-0.24869,-0.7836,-0.569319,-0.24869,-0.708947,-0.51508,-0.481754); -f3(2424,2425,2426,-0.814769,0.447923,-0.368125,-0.677778,0.636476,-0.368125,-0.869397,0.477955,-0.125333); -f3(2427,2428,2429,-0.057904,0.303543,0.951057,0.0194033,0.308407,0.951057,-0.100404,0.526336,0.844328); -f3(2430,2431,2432,0.299309,-0.921177,0.24869,0.0608178,-0.966672,0.24869,0.0627905,-0.998027,0); -f3(2433,2434,2435,0.299309,-0.921177,0.24869,0.0627905,-0.998027,0,0.309017,-0.951057,0); -f3(2436,2437,2438,-0.228144,0.359497,-0.904827,-0.131573,0.40494,-0.904827,-0.341549,0.538195,-0.770513); -f3(2439,2440,2441,-0.057904,0.303543,-0.951057,0.0194033,0.308407,-0.951057,-0.0117658,0.0616783,-0.998027); -f3(2442,2443,2444,-0.131573,-0.40494,0.904827,-0.228144,-0.359497,0.904827,-0.057904,-0.17821,0.982287); -f3(2445,2446,2447,0.0194033,-0.308407,-0.951057,-0.057904,-0.303543,-0.951057,0.00394265,-0.0626666,-0.998027); -f3(2448,2449,2450,0.270794,0.833417,-0.481754,0.469549,0.73989,-0.481754,0.225264,0.69329,-0.684547); -f3(2451,2452,2453,-0.677778,-0.636476,0.368125,-0.869397,-0.477955,0.125333,-0.814769,-0.447923,0.368125); -f3(2454,2455,2456,-0.100404,-0.526336,0.844328,-0.131573,-0.279607,0.951057,-0.228144,-0.484831,0.844328); -f3(2457,2458,2459,-0.677778,-0.636476,0.368125,-0.814769,-0.447923,0.368125,-0.589748,-0.55381,0.587785); -f3(2460,2461,2462,-0.373113,-0.792906,-0.481754,-0.558579,-0.675206,-0.481754,-0.31038,-0.659591,-0.684547); -f3(2463,2464,2465,-0.960946,0.246729,-0.125333,-0.869397,0.477955,-0.125333,-0.869397,0.477955,0.125333); -f3(2466,2467,2468,-0.960946,0.246729,-0.125333,-0.869397,0.477955,0.125333,-0.960946,0.246729,0.125333); -f3(2469,2470,2471,-0.900566,-0.231226,-0.368125,-0.992115,0,-0.125333,-0.960946,-0.246729,-0.125333); -f3(2472,2473,2474,-0.960946,0.246729,-0.125333,-0.960946,0.246729,0.125333,-0.992115,-0,0.125333); -f3(2475,2476,2477,-0.100404,-0.526336,0.844328,-0.228144,-0.484831,0.844328,-0.31038,-0.659591,0.684547); -f3(2478,2479,2480,-0.960946,0.246729,-0.125333,-0.992115,-0,0.125333,-0.992115,0,-0.125333); -f3(2481,2482,2483,-0.100404,-0.526336,0.844328,-0.31038,-0.659591,0.684547,-0.136595,-0.716057,0.684547); -f3(2484,2485,2486,-0.900566,-0.231226,-0.368125,-0.929776,0,-0.368125,-0.992115,0,-0.125333); -f3(2487,2488,2489,-0.464662,0.436347,-0.770513,-0.228144,0.359497,-0.904827,-0.341549,0.538195,-0.770513); -f3(2490,2491,2492,-0.464662,0.436347,-0.770513,-0.341549,0.538195,-0.770513,-0.433493,0.683076,-0.587785); -f3(2493,2494,2495,-0.7836,0.569319,0.24869,-0.637424,0.770513,0,-0.809017,0.587785,0); -f3(2496,2497,2498,-0.7836,0.569319,0.24869,-0.809017,0.587785,0,-0.929776,0.368125,0); -f3(2499,2500,2501,0.119441,0.14438,0.982287,0.344463,0.250267,0.904827,0.151595,0.11014,0.982287); -f3(2502,2503,2504,0.119441,0.14438,0.982287,0.151595,0.11014,0.982287,-0.0400242,-0.0483809,0.998027); -f3(2505,2506,2507,-0.7836,0.569319,0.24869,-0.617398,0.746306,0.24869,-0.637424,0.770513,0); -f3(2508,2509,2510,0.752205,0.297819,0.587785,0.922445,0.116532,0.368125,0.802638,0.101397,0.587785); -f3(2511,2512,2513,-0.464662,0.436347,-0.770513,-0.433493,0.683076,-0.587785,-0.589748,0.55381,-0.587785); -f3(2514,2515,2516,0.0194033,-0.0597173,-0.998027,0.0194033,-0.308407,-0.951057,0.00394265,-0.0626666,-0.998027); -f3(2517,2518,2519,-0.228144,0.484831,0.844328,-0.057904,0.303543,0.951057,-0.100404,0.526336,0.844328); -f3(2520,2521,2522,0.0194033,-0.0597173,-0.998027,0.00394265,-0.0626666,-0.998027,-0.057904,0.17821,-0.982287); -f3(2523,2524,2525,-0.228144,0.484831,0.844328,-0.100404,0.526336,0.844328,-0.136595,0.716057,0.684547); -f3(2526,2527,2528,0.752205,0.297819,0.587785,0.802638,0.101397,0.587785,0.592662,0.234651,0.770513); -f3(2529,2530,2531,-0.228144,0.484831,0.844328,-0.136595,0.716057,0.684547,-0.31038,0.659591,0.684547); -f3(2532,2533,2534,-0.136595,-0.716057,-0.684547,-0.373113,-0.792906,-0.481754,-0.31038,-0.659591,-0.684547); -f3(2535,2536,2537,0.984292,-0.124345,-0.125333,0.922445,-0.365222,-0.125333,0.984292,-0.124345,0.125333); -f3(2538,2539,2540,-0.136595,-0.716057,-0.684547,-0.31038,-0.659591,-0.684547,-0.100404,-0.526336,-0.844328); -f3(2541,2542,2543,0.984292,-0.124345,-0.125333,0.864484,-0.342274,-0.368125,0.922445,-0.365222,-0.125333); -f3(2544,2545,2546,-0.708947,0.389747,-0.587785,-0.677778,0.636476,-0.368125,-0.814769,0.447923,-0.368125); -f3(2547,2548,2549,-0.0117658,-0.187012,0.982287,-0.057904,-0.17821,0.982287,0.00394265,0.0626666,0.998027); -f3(2550,2551,2552,-0.708947,0.389747,-0.587785,-0.464662,0.436347,-0.770513,-0.589748,0.55381,-0.587785); -f3(2553,2554,2555,-0.0117658,-0.187012,0.982287,-0.131573,-0.40494,0.904827,-0.057904,-0.17821,0.982287); -f3(2556,2557,2558,-0.708947,0.389747,-0.587785,-0.589748,0.55381,-0.587785,-0.677778,0.636476,-0.368125); -f3(2559,2560,2561,0.515687,-0.374668,-0.770513,0.271402,-0.328069,-0.904827,0.406309,-0.491144,-0.770513); -f3(2562,2563,2564,-0.100404,0.158211,-0.982287,-0.131573,0.40494,-0.904827,-0.228144,0.359497,-0.904827); -f3(2565,2566,2567,-0.100404,0.158211,-0.982287,-0.057904,0.17821,-0.982287,-0.131573,0.40494,-0.904827); -f3(2568,2569,2570,0.515687,-0.374668,-0.770513,0.406309,-0.491144,-0.770513,0.654508,-0.475528,-0.587785); -f3(2571,2572,2573,-0.433493,-0.683076,0.587785,-0.589748,-0.55381,0.587785,-0.464662,-0.436347,0.770513); -f3(2574,2575,2576,-0.100404,0.158211,-0.982287,0.0194033,-0.0597173,-0.998027,-0.057904,0.17821,-0.982287); -f3(2577,2578,2579,-0.433493,-0.683076,0.587785,-0.464662,-0.436347,0.770513,-0.341549,-0.538195,0.770513); -f3(2580,2581,2582,-0.0267349,0.0568146,-0.998027,-0.057904,0.303543,-0.951057,-0.0117658,0.0616783,-0.998027); -f3(2583,2584,2585,-0.0267349,0.0568146,-0.998027,-0.0117658,0.0616783,-0.998027,0.0797831,-0.169548,-0.982287); -f3(2586,2587,2588,0.0457723,-0.72753,0.684547,-0.136595,-0.716057,0.684547,-0.164203,-0.860785,0.481754); -f3(2589,2590,2591,-0.869397,-0.477955,-0.125333,-0.960946,-0.246729,0.125333,-0.869397,-0.477955,0.125333); -f3(2592,2593,2594,0.0336448,-0.534769,-0.844328,-0.057904,-0.303543,-0.951057,0.0194033,-0.308407,-0.951057); -f3(2595,2596,2597,-0.869397,-0.477955,-0.125333,-0.960946,-0.246729,-0.125333,-0.960946,-0.246729,0.125333); -f3(2598,2599,2600,0.0336448,-0.534769,-0.844328,-0.136595,-0.716057,-0.684547,-0.100404,-0.526336,-0.844328); -f3(2601,2602,2603,0.0457723,-0.72753,0.684547,-0.164203,-0.860785,0.481754,0.0550238,-0.874577,0.481754); -f3(2604,2605,2606,0.0336448,-0.534769,-0.844328,-0.100404,-0.526336,-0.844328,-0.057904,-0.303543,-0.951057); -f3(2607,2608,2609,-0.412403,-0.8764,-0.24869,-0.637424,-0.770513,0,-0.617398,-0.746306,-0.24869); -f3(2610,2611,2612,-0.412403,-0.8764,-0.24869,-0.425779,-0.904827,0,-0.637424,-0.770513,0); -f3(2613,2614,2615,-0.412403,-0.8764,-0.24869,-0.617398,-0.746306,-0.24869,-0.558579,-0.675206,-0.481754); -f3(2616,2617,2618,0.0457723,0.72753,-0.684547,0.225264,0.69329,-0.684547,0.0336448,0.534769,-0.844328); -f3(2619,2620,2621,-0.412403,-0.8764,-0.24869,-0.558579,-0.675206,-0.481754,-0.373113,-0.792906,-0.481754); -f3(2622,2623,2624,-0.900566,0.231226,-0.368125,-0.960946,0.246729,-0.125333,-0.992115,0,-0.125333); -f3(2625,2626,2627,-0.900566,0.231226,-0.368125,-0.869397,0.477955,-0.125333,-0.960946,0.246729,-0.125333); -f3(2628,2629,2630,0.0457723,0.72753,-0.684547,0.270794,0.833417,-0.481754,0.225264,0.69329,-0.684547); -f3(2631,2632,2633,-0.900566,0.231226,-0.368125,-0.992115,0,-0.125333,-0.929776,0,-0.368125); -f3(2634,2635,2636,-0.0267349,-0.0568146,0.998027,-0.196975,-0.238102,0.951057,-0.131573,-0.279607,0.951057); -f3(2637,2638,2639,-0.464662,0.56168,0.684547,-0.31038,0.659591,0.684547,-0.373113,0.792906,0.481754); -f3(2640,2641,2642,-0.900566,0.231226,-0.368125,-0.814769,0.447923,-0.368125,-0.869397,0.477955,-0.125333); -f3(2643,2644,2645,-0.464662,0.56168,0.684547,-0.373113,0.792906,0.481754,-0.558579,0.675206,0.481754); -f3(2646,2647,2648,-0.31038,0.291466,-0.904827,-0.228144,0.359497,-0.904827,-0.464662,0.436347,-0.770513); -f3(2649,2650,2651,-0.0117658,0.0616783,0.998027,-0.0117658,-0.187012,0.982287,0.00394265,0.0626666,0.998027); -f3(2652,2653,2654,-0.0267349,-0.0568146,0.998027,0.119441,0.14438,0.982287,-0.0400242,-0.0483809,0.998027); -f3(2655,2656,2657,-0.0267349,-0.0568146,0.998027,-0.0400242,-0.0483809,0.998027,-0.196975,-0.238102,0.951057); -f3(2658,2659,2660,-0.0117658,0.0616783,0.998027,0.00394265,0.0626666,0.998027,0.0194033,0.308407,0.951057); -f3(2661,2662,2663,0.0954915,-0.293893,-0.951057,0.0194033,-0.308407,-0.951057,0.0194033,-0.0597173,-0.998027); -f3(2664,2665,2666,-0.0117658,0.0616783,0.998027,0.0194033,0.308407,0.951057,-0.057904,0.303543,0.951057); -f3(2667,2668,2669,0.515687,0.374668,0.770513,0.752205,0.297819,0.587785,0.592662,0.234651,0.770513); -f3(2670,2671,2672,0.515687,0.374668,0.770513,0.592662,0.234651,0.770513,0.39588,0.15674,0.904827); -f3(2673,2674,2675,0.515687,0.374668,0.770513,0.39588,0.15674,0.904827,0.344463,0.250267,0.904827); -f3(2676,2677,2678,-0.196975,-0.606226,0.770513,-0.433493,-0.683076,0.587785,-0.341549,-0.538195,0.770513); -f3(2679,2680,2681,-0.164203,-0.860785,-0.481754,-0.373113,-0.792906,-0.481754,-0.136595,-0.716057,-0.684547); -f3(2682,2683,2684,-0.196975,-0.606226,0.770513,-0.341549,-0.538195,0.770513,-0.228144,-0.359497,0.904827); -f3(2685,2686,2687,-0.196975,-0.606226,0.770513,-0.228144,-0.359497,0.904827,-0.131573,-0.40494,0.904827); -f3(2688,2689,2690,0.984292,0.124345,0.125333,0.984292,-0.124345,-0.125333,0.984292,-0.124345,0.125333); -f3(2691,2692,2693,-0.558579,0.307081,-0.770513,-0.31038,0.291466,-0.904827,-0.464662,0.436347,-0.770513); -f3(2694,2695,2696,0.984292,0.124345,0.125333,0.984292,-0.124345,0.125333,0.922445,0.116532,0.368125); -f3(2697,2698,2699,-0.558579,0.307081,-0.770513,-0.464662,0.436347,-0.770513,-0.708947,0.389747,-0.587785); -f3(2700,2701,2702,-0.72322,-0.679149,0.125333,-0.869397,-0.477955,0.125333,-0.677778,-0.636476,0.368125); -f3(2703,2704,2705,-0.72322,-0.679149,0.125333,-0.869397,-0.477955,-0.125333,-0.869397,-0.477955,0.125333); -f3(2706,2707,2708,0.752205,-0.297819,-0.587785,0.752205,-0.546509,-0.368125,0.864484,-0.342274,-0.368125); -f3(2709,2710,2711,0.0336448,-0.0530158,-0.998027,0.0954915,-0.293893,-0.951057,0.0194033,-0.0597173,-0.998027); -f3(2712,2713,2714,0.752205,-0.297819,-0.587785,0.515687,-0.374668,-0.770513,0.654508,-0.475528,-0.587785); -f3(2715,2716,2717,0.0336448,-0.0530158,-0.998027,0.0194033,-0.0597173,-0.998027,-0.100404,0.158211,-0.982287); -f3(2718,2719,2720,0.752205,-0.297819,-0.587785,0.654508,-0.475528,-0.587785,0.752205,-0.546509,-0.368125); -f3(2721,2722,2723,-0.7836,-0.201194,-0.587785,-0.929776,0,-0.368125,-0.900566,-0.231226,-0.368125); -f3(2724,2725,2726,-0.7836,-0.201194,-0.587785,-0.809017,0,-0.587785,-0.929776,0,-0.368125); -f3(2727,2728,2729,0.119441,-0.14438,-0.982287,0.181288,-0.385257,-0.904827,0.271402,-0.328069,-0.904827); -f3(2730,2731,2732,0.0457723,-0.72753,-0.684547,-0.136595,-0.716057,-0.684547,0.0336448,-0.534769,-0.844328); -f3(2733,2734,2735,0.119441,-0.14438,-0.982287,-0.0267349,0.0568146,-0.998027,0.0797831,-0.169548,-0.982287); -f3(2736,2737,2738,0.119441,-0.14438,-0.982287,0.0797831,-0.169548,-0.982287,0.181288,-0.385257,-0.904827); -f3(2739,2740,2741,0.0457723,-0.72753,-0.684547,-0.164203,-0.860785,-0.481754,-0.136595,-0.716057,-0.684547); -f3(2742,2743,2744,-0.708947,0.51508,0.481754,-0.558579,0.675206,0.481754,-0.617398,0.746306,0.24869); -f3(2745,2746,2747,-0.7836,0.201194,-0.587785,-0.929776,0,-0.368125,-0.809017,0,-0.587785); -f3(2748,2749,2750,-0.7836,0.201194,-0.587785,-0.708947,0.389747,-0.587785,-0.814769,0.447923,-0.368125); -f3(2751,2752,2753,-0.708947,0.51508,0.481754,-0.617398,0.746306,0.24869,-0.7836,0.569319,0.24869); -f3(2754,2755,2756,-0.7836,0.201194,-0.587785,-0.900566,0.231226,-0.368125,-0.929776,0,-0.368125); -f3(2757,2758,2759,-0.7836,0.201194,-0.587785,-0.814769,0.447923,-0.368125,-0.900566,0.231226,-0.368125); -f3(2760,2761,2762,0.270794,-0.833417,0.481754,0.0608178,-0.966672,0.24869,0.299309,-0.921177,0.24869); -f3(2763,2764,2765,-0.136595,0.128271,-0.982287,-0.228144,0.359497,-0.904827,-0.31038,0.291466,-0.904827); -f3(2766,2767,2768,0.270794,-0.833417,0.481754,0.0550238,-0.874577,0.481754,0.0608178,-0.966672,0.24869); -f3(2769,2770,2771,-0.100404,0.526336,-0.844328,0.0336448,0.534769,-0.844328,0.0194033,0.308407,-0.951057); -f3(2772,2773,2774,-0.136595,0.128271,-0.982287,-0.100404,0.158211,-0.982287,-0.228144,0.359497,-0.904827); -f3(2775,2776,2777,-0.131573,0.279607,0.951057,-0.057904,0.303543,0.951057,-0.228144,0.484831,0.844328); -f3(2778,2779,2780,-0.100404,0.526336,-0.844328,0.0194033,0.308407,-0.951057,-0.057904,0.303543,-0.951057); -f3(2781,2782,2783,-0.100404,0.526336,-0.844328,0.0457723,0.72753,-0.684547,0.0336448,0.534769,-0.844328); -f3(2784,2785,2786,0.16558,-0.509602,-0.844328,0.0194033,-0.308407,-0.951057,0.0954915,-0.293893,-0.951057); -f3(2787,2788,2789,-0.057904,-0.303543,0.951057,-0.131573,-0.279607,0.951057,-0.100404,-0.526336,0.844328); -f3(2790,2791,2792,0.16558,-0.509602,-0.844328,0.0336448,-0.534769,-0.844328,0.0194033,-0.308407,-0.951057); -f3(2793,2794,2795,-0.0267349,-0.424939,0.904827,-0.131573,-0.40494,0.904827,-0.0117658,-0.187012,0.982287); -f3(2796,2797,2798,0.16558,-0.509602,-0.844328,0.0457723,-0.72753,-0.684547,0.0336448,-0.534769,-0.844328); -f3(2799,2800,2801,-0.181494,-0.951427,-0.24869,-0.187381,-0.982287,0,-0.425779,-0.904827,0); -f3(2802,2803,2804,0.299309,0.921177,-0.24869,0.309017,0.951057,-0,0.535827,0.844328,-0); -f3(2805,2806,2807,0.299309,0.921177,-0.24869,0.0627905,0.998027,-0,0.309017,0.951057,-0); -f3(2808,2809,2810,-0.181494,-0.951427,-0.24869,-0.425779,-0.904827,0,-0.412403,-0.8764,-0.24869); -f3(2811,2812,2813,-0.498199,-0.785036,0.368125,-0.677778,-0.636476,0.368125,-0.589748,-0.55381,0.587785); -f3(2814,2815,2816,0.299309,0.921177,-0.24869,0.518993,0.817802,-0.24869,0.469549,0.73989,-0.481754); -f3(2817,2818,2819,-0.181494,-0.951427,-0.24869,-0.412403,-0.8764,-0.24869,-0.373113,-0.792906,-0.481754); -f3(2820,2821,2822,0.299309,0.921177,-0.24869,0.469549,0.73989,-0.481754,0.270794,0.833417,-0.481754); -f3(2823,2824,2825,-0.181494,-0.951427,-0.24869,-0.373113,-0.792906,-0.481754,-0.164203,-0.860785,-0.481754); -f3(2826,2827,2828,0.299309,0.921177,-0.24869,0.535827,0.844328,-0,0.518993,0.817802,-0.24869); -f3(2829,2830,2831,-0.498199,-0.785036,0.368125,-0.72322,-0.679149,0.125333,-0.677778,-0.636476,0.368125); -f3(2832,2833,2834,-0.373113,0.205121,-0.904827,-0.31038,0.291466,-0.904827,-0.558579,0.307081,-0.770513); -f3(2835,2836,2837,-0.498199,-0.785036,0.368125,-0.589748,-0.55381,0.587785,-0.433493,-0.683076,0.587785); -f3(2838,2839,2840,0.271402,0.328069,0.904827,0.344463,0.250267,0.904827,0.119441,0.14438,0.982287); -f3(2841,2842,2843,-0.814769,-0.447923,-0.368125,-0.960946,-0.246729,-0.125333,-0.869397,-0.477955,-0.125333); -f3(2844,2845,2846,0.16558,-0.260912,-0.951057,0.0954915,-0.293893,-0.951057,0.0336448,-0.0530158,-0.998027); -f3(2847,2848,2849,-0.814769,-0.447923,-0.368125,-0.900566,-0.231226,-0.368125,-0.960946,-0.246729,-0.125333); -f3(2850,2851,2852,0.864484,0.342274,0.368125,0.922445,0.116532,0.368125,0.752205,0.297819,0.587785); -f3(2853,2854,2855,-0.900566,0.356559,0.24869,-0.7836,0.569319,0.24869,-0.929776,0.368125,0); -f3(2856,2857,2858,0.864484,0.342274,0.368125,0.984292,0.124345,0.125333,0.922445,0.116532,0.368125); -f3(2859,2860,2861,0.0550238,-0.874577,-0.481754,-0.164203,-0.860785,-0.481754,0.0457723,-0.72753,-0.684547); -f3(2862,2863,2864,-0.900566,0.356559,0.24869,-0.929776,0.368125,0,-0.992115,0.125333,0); -f3(2865,2866,2867,-0.617398,0.158521,-0.770513,-0.558579,0.307081,-0.770513,-0.708947,0.389747,-0.587785); -f3(2868,2869,2870,-0.617398,0.158521,-0.770513,-0.373113,0.205121,-0.904827,-0.558579,0.307081,-0.770513); -f3(2871,2872,2873,-0.341549,0.412862,0.844328,-0.228144,0.484831,0.844328,-0.31038,0.659591,0.684547); -f3(2874,2875,2876,-0.617398,0.158521,-0.770513,-0.809017,0,-0.587785,-0.637424,0,-0.770513); -f3(2877,2878,2879,-0.617398,0.158521,-0.770513,-0.637424,0,-0.770513,-0.425779,0,-0.904827); -f3(2880,2881,2882,0.922445,-0.116532,-0.368125,0.864484,-0.342274,-0.368125,0.984292,-0.124345,-0.125333); -f3(2883,2884,2885,-0.617398,0.158521,-0.770513,-0.7836,0.201194,-0.587785,-0.809017,0,-0.587785); -f3(2886,2887,2888,-0.617398,0.158521,-0.770513,-0.708947,0.389747,-0.587785,-0.7836,0.201194,-0.587785); -f3(2889,2890,2891,-0.341549,0.412862,0.844328,-0.131573,0.279607,0.951057,-0.228144,0.484831,0.844328); -f3(2892,2893,2894,0.0457723,-0.0429831,-0.998027,-0.100404,0.158211,-0.982287,-0.136595,0.128271,-0.982287); -f3(2895,2896,2897,-0.341549,0.412862,0.844328,-0.31038,0.659591,0.684547,-0.464662,0.56168,0.684547); -f3(2898,2899,2900,0.344463,-0.250267,-0.904827,0.271402,-0.328069,-0.904827,0.515687,-0.374668,-0.770513); -f3(2901,2902,2903,0.0457723,-0.0429831,-0.998027,0.16558,-0.260912,-0.951057,0.0336448,-0.0530158,-0.998027); -f3(2904,2905,2906,0.0457723,-0.0429831,-0.998027,0.0336448,-0.0530158,-0.998027,-0.100404,0.158211,-0.982287); -f3(2907,2908,2909,0.225264,-0.69329,-0.684547,0.0550238,-0.874577,-0.481754,0.0457723,-0.72753,-0.684547); -f3(2910,2911,2912,0.0351118,-0.184062,0.982287,-0.0117658,-0.187012,0.982287,-0.0117658,0.0616783,0.998027); -f3(2913,2914,2915,0.225264,-0.69329,-0.684547,0.0457723,-0.72753,-0.684547,0.16558,-0.509602,-0.844328); -f3(2916,2917,2918,0.0351118,-0.184062,0.982287,-0.0267349,-0.424939,0.904827,-0.0117658,-0.187012,0.982287); -f3(2919,2920,2921,-0.131573,0.279607,-0.951057,-0.057904,0.303543,-0.951057,-0.0267349,0.0568146,-0.998027); -f3(2922,2923,2924,-0.164203,0.0902716,-0.982287,-0.31038,0.291466,-0.904827,-0.373113,0.205121,-0.904827); -f3(2925,2926,2927,-0.164203,0.0902716,-0.982287,0.0457723,-0.0429831,-0.998027,-0.136595,0.128271,-0.982287); -f3(2928,2929,2930,0.518993,-0.817802,0.24869,0.299309,-0.921177,0.24869,0.309017,-0.951057,0); -f3(2931,2932,2933,-0.25,-0.769421,0.587785,-0.498199,-0.785036,0.368125,-0.433493,-0.683076,0.587785); -f3(2934,2935,2936,-0.164203,0.0902716,-0.982287,-0.136595,0.128271,-0.982287,-0.31038,0.291466,-0.904827); -f3(2937,2938,2939,-0.25,-0.769421,0.587785,-0.433493,-0.683076,0.587785,-0.196975,-0.606226,0.770513); -f3(2940,2941,2942,0.518993,-0.817802,0.24869,0.309017,-0.951057,0,0.535827,-0.844328,0); -f3(2943,2944,2945,0.518993,-0.817802,0.24869,0.535827,-0.844328,0,0.728969,-0.684547,0); -f3(2946,2947,2948,0.28711,-0.452414,-0.844328,0.0954915,-0.293893,-0.951057,0.16558,-0.260912,-0.951057); -f3(2949,2950,2951,0.28711,-0.452414,-0.844328,0.16558,-0.509602,-0.844328,0.0954915,-0.293893,-0.951057); -f3(2952,2953,2954,-0.72322,-0.679149,-0.125333,-0.869397,-0.477955,-0.125333,-0.72322,-0.679149,0.125333); -f3(2955,2956,2957,0.0336448,-0.534769,0.844328,-0.136595,-0.716057,0.684547,0.0457723,-0.72753,0.684547); -f3(2958,2959,2960,0.28711,-0.452414,-0.844328,0.225264,-0.69329,-0.684547,0.16558,-0.509602,-0.844328); -f3(2961,2962,2963,-0.72322,-0.679149,-0.125333,-0.814769,-0.447923,-0.368125,-0.869397,-0.477955,-0.125333); -f3(2964,2965,2966,0.0336448,-0.534769,0.844328,-0.057904,-0.303543,0.951057,-0.100404,-0.526336,0.844328); -f3(2967,2968,2969,0.0608178,-0.966672,-0.24869,-0.181494,-0.951427,-0.24869,-0.164203,-0.860785,-0.481754); -f3(2970,2971,2972,0.0336448,-0.534769,0.844328,-0.100404,-0.526336,0.844328,-0.136595,-0.716057,0.684547); -f3(2973,2974,2975,0.0608178,-0.966672,-0.24869,-0.164203,-0.860785,-0.481754,0.0550238,-0.874577,-0.481754); -f3(2976,2977,2978,0.0608178,-0.966672,-0.24869,0.0627905,-0.998027,0,-0.187381,-0.982287,0); -f3(2979,2980,2981,-0.617398,-0.158521,-0.770513,-0.809017,0,-0.587785,-0.7836,-0.201194,-0.587785); -f3(2982,2983,2984,0.0550238,0.874577,-0.481754,0.270794,0.833417,-0.481754,0.0457723,0.72753,-0.684547); -f3(2985,2986,2987,0.0608178,-0.966672,-0.24869,-0.187381,-0.982287,0,-0.181494,-0.951427,-0.24869); -f3(2988,2989,2990,-0.617398,-0.158521,-0.770513,-0.637424,0,-0.770513,-0.809017,0,-0.587785); -f3(2991,2992,2993,-0.412403,0.105887,-0.904827,-0.617398,0.158521,-0.770513,-0.425779,0,-0.904827); -f3(2994,2995,2996,-0.617398,-0.158521,-0.770513,-0.425779,0,-0.904827,-0.637424,0,-0.770513); -f3(2997,2998,2999,0.0797831,0.169548,0.982287,0.119441,0.14438,0.982287,-0.0267349,-0.0568146,0.998027); -f3(3000,3001,3002,0.0797831,0.169548,0.982287,0.271402,0.328069,0.904827,0.119441,0.14438,0.982287); -f3(3003,3004,3005,-0.412403,0.105887,-0.904827,-0.373113,0.205121,-0.904827,-0.617398,0.158521,-0.770513); -f3(3006,3007,3008,0.225264,-0.211537,-0.951057,0.16558,-0.260912,-0.951057,0.0457723,-0.0429831,-0.998027); -f3(3009,3010,3011,0.654508,0.475528,0.587785,0.864484,0.342274,0.368125,0.752205,0.297819,0.587785); -f3(3012,3013,3014,-0.589748,0.428477,0.684547,-0.558579,0.675206,0.481754,-0.708947,0.51508,0.481754); -f3(3015,3016,3017,0.270794,-0.833417,-0.481754,0.0550238,-0.874577,-0.481754,0.225264,-0.69329,-0.684547); -f3(3018,3019,3020,-0.589748,0.428477,0.684547,-0.464662,0.56168,0.684547,-0.558579,0.675206,0.481754); -f3(3021,3022,3023,0.654508,0.475528,0.587785,0.752205,0.297819,0.587785,0.515687,0.374668,0.770513); -f3(3024,3025,3026,-0.0267349,0.0568146,0.998027,-0.0117658,0.0616783,0.998027,-0.057904,0.303543,0.951057); -f3(3027,3028,3029,0.0550238,-0.0302496,-0.998027,0.225264,-0.211537,-0.951057,0.0457723,-0.0429831,-0.998027); -f3(3030,3031,3032,-0.0267349,0.0568146,0.998027,-0.057904,0.303543,0.951057,-0.131573,0.279607,0.951057); -f3(3033,3034,3035,-0.0267349,0.0568146,0.998027,0.0351118,-0.184062,0.982287,-0.0117658,0.0616783,0.998027); -f3(3036,3037,3038,0.984292,0.124345,-0.125333,0.984292,-0.124345,-0.125333,0.984292,0.124345,0.125333); -f3(3039,3040,3041,0.0550238,-0.0302496,-0.998027,0.0457723,-0.0429831,-0.998027,-0.164203,0.0902716,-0.982287); -f3(3042,3043,3044,0.984292,0.124345,-0.125333,0.922445,-0.116532,-0.368125,0.984292,-0.124345,-0.125333); -f3(3045,3046,3047,-0.0400242,-0.636166,0.770513,-0.25,-0.769421,0.587785,-0.196975,-0.606226,0.770513); -f3(3048,3049,3050,0.390601,-0.615489,-0.684547,0.225264,-0.69329,-0.684547,0.28711,-0.452414,-0.844328); -f3(3051,3052,3053,0.390601,-0.615489,-0.684547,0.270794,-0.833417,-0.481754,0.225264,-0.69329,-0.684547); -f3(3054,3055,3056,-0.0400242,-0.636166,0.770513,-0.131573,-0.40494,0.904827,-0.0267349,-0.424939,0.904827); -f3(3057,3058,3059,0.592662,-0.234651,-0.770513,0.515687,-0.374668,-0.770513,0.752205,-0.297819,-0.587785); -f3(3060,3061,3062,-0.181494,0.0465998,-0.982287,-0.373113,0.205121,-0.904827,-0.412403,0.105887,-0.904827); -f3(3063,3064,3065,-0.0400242,-0.636166,0.770513,-0.196975,-0.606226,0.770513,-0.131573,-0.40494,0.904827); -f3(3066,3067,3068,-0.181494,0.0465998,-0.982287,-0.412403,0.105887,-0.904827,-0.425779,0,-0.904827); -f3(3069,3070,3071,0.592662,-0.234651,-0.770513,0.344463,-0.250267,-0.904827,0.515687,-0.374668,-0.770513); -f3(3072,3073,3074,-0.181494,0.0465998,-0.982287,-0.425779,0,-0.904827,-0.187381,0,-0.982287); -f3(3075,3076,3077,-0.181494,0.0465998,-0.982287,-0.164203,0.0902716,-0.982287,-0.373113,0.205121,-0.904827); -f3(3078,3079,3080,0.390601,-0.366799,-0.844328,0.16558,-0.260912,-0.951057,0.225264,-0.211537,-0.951057); -f3(3081,3082,3083,-0.0400242,0.0483809,-0.998027,-0.0267349,0.0568146,-0.998027,0.119441,-0.14438,-0.982287); -f3(3084,3085,3086,0.390601,-0.366799,-0.844328,0.28711,-0.452414,-0.844328,0.16558,-0.260912,-0.951057); -f3(3087,3088,3089,-0.531602,-0.83767,0.125333,-0.72322,-0.679149,0.125333,-0.498199,-0.785036,0.368125); -f3(3090,3091,3092,-0.0400242,0.0483809,-0.998027,-0.131573,0.279607,-0.951057,-0.0267349,0.0568146,-0.998027); -f3(3093,3094,3095,-0.708947,-0.389747,-0.587785,-0.7836,-0.201194,-0.587785,-0.900566,-0.231226,-0.368125); -f3(3096,3097,3098,-0.708947,-0.389747,-0.587785,-0.900566,-0.231226,-0.368125,-0.814769,-0.447923,-0.368125); -f3(3099,3100,3101,0.225264,-0.69329,0.684547,0.0457723,-0.72753,0.684547,0.0550238,-0.874577,0.481754); -f3(3102,3103,3104,0.299309,-0.921177,-0.24869,0.309017,-0.951057,0,0.0627905,-0.998027,0); -f3(3105,3106,3107,0.225264,-0.69329,0.684547,0.0550238,-0.874577,0.481754,0.270794,-0.833417,0.481754); -f3(3108,3109,3110,0.299309,-0.921177,-0.24869,0.0627905,-0.998027,0,0.0608178,-0.966672,-0.24869); -f3(3111,3112,3113,-0.136595,0.716057,-0.684547,0.0550238,0.874577,-0.481754,0.0457723,0.72753,-0.684547); -f3(3114,3115,3116,0.299309,-0.921177,-0.24869,0.0608178,-0.966672,-0.24869,0.0550238,-0.874577,-0.481754); -f3(3117,3118,3119,-0.814769,0.32259,0.481754,-0.708947,0.51508,0.481754,-0.7836,0.569319,0.24869); -f3(3120,3121,3122,0.299309,-0.921177,-0.24869,0.0550238,-0.874577,-0.481754,0.270794,-0.833417,-0.481754); -f3(3123,3124,3125,-0.814769,0.32259,0.481754,-0.7836,0.569319,0.24869,-0.900566,0.356559,0.24869); -f3(3126,3127,3128,-0.136595,0.716057,-0.684547,0.0457723,0.72753,-0.684547,-0.100404,0.526336,-0.844328); -f3(3129,3130,3131,0.270794,-0.14887,-0.951057,0.225264,-0.211537,-0.951057,0.0550238,-0.0302496,-0.998027); -f3(3132,3133,3134,-0.0117658,-0.0616783,0.998027,-0.131573,-0.279607,0.951057,-0.057904,-0.303543,0.951057); -f3(3135,3136,3137,0.469549,-0.73989,-0.481754,0.270794,-0.833417,-0.481754,0.390601,-0.615489,-0.684547); -f3(3138,3139,3140,-0.0117658,-0.0616783,0.998027,-0.0267349,-0.0568146,0.998027,-0.131573,-0.279607,0.951057); -f3(3141,3142,3143,0.0608178,-0.0156154,-0.998027,-0.164203,0.0902716,-0.982287,-0.181494,0.0465998,-0.982287); -f3(3144,3145,3146,-0.196975,0.238102,0.951057,-0.131573,0.279607,0.951057,-0.341549,0.412862,0.844328); -f3(3147,3148,3149,-0.0117658,-0.0616783,0.998027,0.0797831,0.169548,0.982287,-0.0267349,-0.0568146,0.998027); -f3(3150,3151,3152,0.0608178,-0.0156154,-0.998027,0.0550238,-0.0302496,-0.998027,-0.164203,0.0902716,-0.982287); -f3(3153,3154,3155,0.0608178,-0.0156154,-0.998027,-0.187381,0,-0.982287,0.0627905,0,-0.998027); -f3(3156,3157,3158,0.0608178,-0.0156154,-0.998027,0.0627905,0,-0.998027,0.309017,0,-0.951057); -f3(3159,3160,3161,0.0608178,-0.0156154,-0.998027,0.270794,-0.14887,-0.951057,0.0550238,-0.0302496,-0.998027); -f3(3162,3163,3164,0.0608178,-0.0156154,-0.998027,-0.181494,0.0465998,-0.982287,-0.187381,0,-0.982287); -f3(3165,3166,3167,0.406309,0.491144,0.770513,0.515687,0.374668,0.770513,0.344463,0.250267,0.904827); -f3(3168,3169,3170,0.531395,-0.499013,-0.684547,0.28711,-0.452414,-0.844328,0.390601,-0.366799,-0.844328); -f3(3171,3172,3173,0.0797831,-0.418238,0.904827,-0.0267349,-0.424939,0.904827,0.0351118,-0.184062,0.982287); -f3(3174,3175,3176,0.406309,0.491144,0.770513,0.344463,0.250267,0.904827,0.271402,0.328069,0.904827); -f3(3177,3178,3179,0.406309,0.491144,0.770513,0.654508,0.475528,0.587785,0.515687,0.374668,0.770513); -f3(3180,3181,3182,0.531395,-0.499013,-0.684547,0.469549,-0.73989,-0.481754,0.390601,-0.615489,-0.684547); -f3(3183,3184,3185,0.922445,0.365222,0.125333,0.984292,0.124345,-0.125333,0.984292,0.124345,0.125333); -f3(3186,3187,3188,0.531395,-0.499013,-0.684547,0.390601,-0.615489,-0.684547,0.28711,-0.452414,-0.844328); -f3(3189,3190,3191,0.469549,-0.258137,-0.844328,0.390601,-0.366799,-0.844328,0.225264,-0.211537,-0.951057); -f3(3192,3193,3194,-0.287317,-0.88427,0.368125,-0.498199,-0.785036,0.368125,-0.25,-0.769421,0.587785); -f3(3195,3196,3197,0.922445,0.365222,0.125333,0.984292,0.124345,0.125333,0.864484,0.342274,0.368125); -f3(3198,3199,3200,0.469549,-0.258137,-0.844328,0.531395,-0.499013,-0.684547,0.390601,-0.366799,-0.844328); -f3(3201,3202,3203,-0.287317,-0.88427,0.368125,-0.531602,-0.83767,0.125333,-0.498199,-0.785036,0.368125); -f3(3204,3205,3206,0.469549,-0.258137,-0.844328,0.225264,-0.211537,-0.951057,0.270794,-0.14887,-0.951057); -f3(3207,3208,3209,0.802638,-0.101397,-0.587785,0.592662,-0.234651,-0.770513,0.752205,-0.297819,-0.587785); -f3(3210,3211,3212,0.802638,-0.101397,-0.587785,0.752205,-0.297819,-0.587785,0.864484,-0.342274,-0.368125); -f3(3213,3214,3215,0.518993,-0.817802,-0.24869,0.270794,-0.833417,-0.481754,0.469549,-0.73989,-0.481754); -f3(3216,3217,3218,0.518993,-0.817802,-0.24869,0.535827,-0.844328,0,0.309017,-0.951057,0); -f3(3219,3220,3221,0.518993,-0.817802,-0.24869,0.728969,-0.684547,0,0.535827,-0.844328,0); -f3(3222,3223,3224,-0.677778,-0.636476,-0.368125,-0.814769,-0.447923,-0.368125,-0.72322,-0.679149,-0.125333); -f3(3225,3226,3227,0.802638,-0.101397,-0.587785,0.864484,-0.342274,-0.368125,0.922445,-0.116532,-0.368125); -f3(3228,3229,3230,0.518993,-0.817802,-0.24869,0.299309,-0.921177,-0.24869,0.270794,-0.833417,-0.481754); -f3(3231,3232,3233,0.518993,-0.817802,-0.24869,0.309017,-0.951057,0,0.299309,-0.921177,-0.24869); -f3(3234,3235,3236,0.299309,-0.0768494,-0.951057,0.0608178,-0.0156154,-0.998027,0.309017,0,-0.951057); -f3(3237,3238,3239,0.151595,-0.11014,-0.982287,-0.0400242,0.0483809,-0.998027,0.119441,-0.14438,-0.982287); -f3(3240,3241,3242,0.299309,-0.0768494,-0.951057,0.270794,-0.14887,-0.951057,0.0608178,-0.0156154,-0.998027); -f3(3243,3244,3245,-0.412403,-0.105887,-0.904827,-0.425779,0,-0.904827,-0.617398,-0.158521,-0.770513); -f3(3246,3247,3248,0.151595,-0.11014,-0.982287,0.119441,-0.14438,-0.982287,0.271402,-0.328069,-0.904827); -f3(3249,3250,3251,0.151595,-0.11014,-0.982287,0.271402,-0.328069,-0.904827,0.344463,-0.250267,-0.904827); -f3(3252,3253,3254,0.6388,-0.599873,-0.481754,0.469549,-0.73989,-0.481754,0.531395,-0.499013,-0.684547); -f3(3255,3256,3257,-0.960946,0.121396,0.24869,-0.900566,0.356559,0.24869,-0.992115,0.125333,0); -f3(3258,3259,3260,0.469549,-0.73989,0.481754,0.270794,-0.833417,0.481754,0.299309,-0.921177,0.24869); -f3(3261,3262,3263,0.469549,-0.73989,0.481754,0.299309,-0.921177,0.24869,0.518993,-0.817802,0.24869); -f3(3264,3265,3266,0.6388,-0.351183,-0.684547,0.531395,-0.499013,-0.684547,0.469549,-0.258137,-0.844328); -f3(3267,3268,3269,0.6388,-0.351183,-0.684547,0.6388,-0.599873,-0.481754,0.531395,-0.499013,-0.684547); -f3(3270,3271,3272,-0.433493,0.314951,0.844328,-0.196975,0.238102,0.951057,-0.341549,0.412862,0.844328); -f3(3273,3274,3275,0.518993,-0.133255,-0.844328,0.309017,0,-0.951057,0.535827,0,-0.844328); -f3(3276,3277,3278,-0.228144,0.484831,-0.844328,-0.136595,0.716057,-0.684547,-0.100404,0.526336,-0.844328); -f3(3279,3280,3281,-0.433493,0.314951,0.844328,-0.464662,0.56168,0.684547,-0.589748,0.428477,0.684547); -f3(3282,3283,3284,-0.228144,0.484831,-0.844328,-0.100404,0.526336,-0.844328,-0.057904,0.303543,-0.951057); -f3(3285,3286,3287,0.518993,-0.133255,-0.844328,0.469549,-0.258137,-0.844328,0.270794,-0.14887,-0.951057); -f3(3288,3289,3290,-0.228144,0.484831,-0.844328,-0.057904,0.303543,-0.951057,-0.131573,0.279607,-0.951057); -f3(3291,3292,3293,0.518993,-0.133255,-0.844328,0.299309,-0.0768494,-0.951057,0.309017,0,-0.951057); -f3(3294,3295,3296,-0.433493,0.314951,0.844328,-0.341549,0.412862,0.844328,-0.464662,0.56168,0.684547); -f3(3297,3298,3299,0.518993,-0.133255,-0.844328,0.270794,-0.14887,-0.951057,0.299309,-0.0768494,-0.951057); -f3(3300,3301,3302,0.0194033,-0.308407,0.951057,-0.057904,-0.303543,0.951057,0.0336448,-0.534769,0.844328); -f3(3303,3304,3305,0.706067,-0.663041,-0.24869,0.518993,-0.817802,-0.24869,0.469549,-0.73989,-0.481754); -f3(3306,3307,3308,0.706067,-0.663041,-0.24869,0.728969,-0.684547,0,0.518993,-0.817802,-0.24869); -f3(3309,3310,3311,0.706067,-0.663041,-0.24869,0.469549,-0.73989,-0.481754,0.6388,-0.599873,-0.481754); -f3(3312,3313,3314,0.0797831,-0.169548,0.982287,0.0351118,-0.184062,0.982287,-0.0267349,0.0568146,0.998027); -f3(3315,3316,3317,0.0608178,0.966672,-0.24869,0.270794,0.833417,-0.481754,0.0550238,0.874577,-0.481754); -f3(3318,3319,3320,0.0797831,-0.169548,0.982287,0.0797831,-0.418238,0.904827,0.0351118,-0.184062,0.982287); -f3(3321,3322,3323,0.0608178,0.966672,-0.24869,0.0627905,0.998027,-0,0.299309,0.921177,-0.24869); -f3(3324,3325,3326,0.0608178,0.966672,-0.24869,0.299309,0.921177,-0.24869,0.270794,0.833417,-0.481754); -f3(3327,3328,3329,0.767913,-0.422164,-0.481754,0.6388,-0.599873,-0.481754,0.6388,-0.351183,-0.684547); -f3(3330,3331,3332,0.706067,-0.181287,-0.684547,0.535827,0,-0.844328,0.728969,0,-0.684547); -f3(3333,3334,3335,0.706067,-0.181287,-0.684547,0.728969,0,-0.684547,0.876307,0,-0.481754); -f3(3336,3337,3338,0.706067,-0.181287,-0.684547,0.767913,-0.422164,-0.481754,0.6388,-0.351183,-0.684547); -f3(3339,3340,3341,-0.0507986,-0.807421,0.587785,-0.25,-0.769421,0.587785,-0.0400242,-0.636166,0.770513); -f3(3342,3343,3344,0.706067,-0.181287,-0.684547,0.518993,-0.133255,-0.844328,0.535827,0,-0.844328); -f3(3345,3346,3347,-0.0507986,-0.807421,0.587785,-0.287317,-0.88427,0.368125,-0.25,-0.769421,0.587785); -f3(3348,3349,3350,0.706067,-0.181287,-0.684547,0.6388,-0.351183,-0.684547,0.469549,-0.258137,-0.844328); -f3(3351,3352,3353,-0.531602,-0.83767,-0.125333,-0.72322,-0.679149,-0.125333,-0.72322,-0.679149,0.125333); -f3(3354,3355,3356,0.181288,0.385257,0.904827,0.271402,0.328069,0.904827,0.0797831,0.169548,0.982287); -f3(3357,3358,3359,0.706067,-0.181287,-0.684547,0.469549,-0.258137,-0.844328,0.518993,-0.133255,-0.844328); -f3(3360,3361,3362,0.848776,-0.466619,-0.24869,0.876307,-0.481754,0,0.728969,-0.684547,0); -f3(3363,3364,3365,0.848776,-0.466619,-0.24869,0.728969,-0.684547,0,0.706067,-0.663041,-0.24869); -f3(3366,3367,3368,0.848776,-0.466619,-0.24869,0.968583,-0.24869,0,0.876307,-0.481754,0); -f3(3369,3370,3371,-0.531602,-0.83767,-0.125333,-0.72322,-0.679149,0.125333,-0.531602,-0.83767,0.125333); -f3(3372,3373,3374,0.848776,-0.466619,-0.24869,0.706067,-0.663041,-0.24869,0.6388,-0.599873,-0.481754); -f3(3375,3376,3377,0.752205,0.546509,0.368125,0.922445,0.365222,0.125333,0.864484,0.342274,0.368125); -f3(3378,3379,3380,0.848776,-0.466619,-0.24869,0.6388,-0.599873,-0.481754,0.767913,-0.422164,-0.481754); -f3(3381,3382,3383,0.848776,-0.217929,-0.481754,0.706067,-0.181287,-0.684547,0.876307,0,-0.481754); -f3(3384,3385,3386,0.848776,-0.217929,-0.481754,0.767913,-0.422164,-0.481754,0.706067,-0.181287,-0.684547); -f3(3387,3388,3389,0.752205,0.546509,0.368125,0.864484,0.342274,0.368125,0.654508,0.475528,0.587785); -f3(3390,3391,3392,-0.558579,-0.307081,-0.770513,-0.412403,-0.105887,-0.904827,-0.617398,-0.158521,-0.770513); -f3(3393,3394,3395,0.938153,-0.240877,-0.24869,0.767913,-0.422164,-0.481754,0.848776,-0.217929,-0.481754); -f3(3396,3397,3398,0.938153,-0.240877,-0.24869,1,0,-0,0.968583,-0.24869,0); -f3(3399,3400,3401,0.938153,-0.240877,-0.24869,0.876307,0,-0.481754,0.968583,0,-0.24869); -f3(3402,3403,3404,-0.558579,-0.307081,-0.770513,-0.7836,-0.201194,-0.587785,-0.708947,-0.389747,-0.587785); -f3(3405,3406,3407,0.922445,0.116532,-0.368125,0.922445,-0.116532,-0.368125,0.984292,0.124345,-0.125333); -f3(3408,3409,3410,0.938153,-0.240877,-0.24869,0.968583,0,-0.24869,1,0,-0); -f3(3411,3412,3413,-0.558579,-0.307081,-0.770513,-0.617398,-0.158521,-0.770513,-0.7836,-0.201194,-0.587785); -f3(3414,3415,3416,0.938153,-0.240877,-0.24869,0.848776,-0.217929,-0.481754,0.876307,0,-0.481754); -f3(3417,3418,3419,0.938153,-0.240877,-0.24869,0.968583,-0.24869,0,0.848776,-0.466619,-0.24869); -f3(3420,3421,3422,0.938153,-0.240877,-0.24869,0.848776,-0.466619,-0.24869,0.767913,-0.422164,-0.481754); -f3(3423,3424,3425,-0.677778,0.268351,0.684547,-0.589748,0.428477,0.684547,-0.708947,0.51508,0.481754); -f3(3426,3427,3428,0.39588,-0.15674,-0.904827,0.344463,-0.250267,-0.904827,0.592662,-0.234651,-0.770513); -f3(3429,3430,3431,-0.677778,0.268351,0.684547,-0.708947,0.51508,0.481754,-0.814769,0.32259,0.481754); -f3(3432,3433,3434,-0.0400242,0.0483809,0.998027,0.0797831,-0.169548,0.982287,-0.0267349,0.0568146,0.998027); -f3(3435,3436,3437,-0.196975,0.238102,-0.951057,-0.131573,0.279607,-0.951057,-0.0400242,0.0483809,-0.998027); -f3(3438,3439,3440,-0.0400242,0.0483809,0.998027,-0.0267349,0.0568146,0.998027,-0.131573,0.279607,0.951057); -f3(3441,3442,3443,-0.0400242,0.0483809,0.998027,-0.131573,0.279607,0.951057,-0.196975,0.238102,0.951057); -f3(3444,3445,3446,0.706067,-0.663041,0.24869,0.518993,-0.817802,0.24869,0.728969,-0.684547,0); -f3(3447,3448,3449,0.119441,-0.626133,0.770513,-0.0507986,-0.807421,0.587785,-0.0400242,-0.636166,0.770513); -f3(3450,3451,3452,0.16558,-0.509602,0.844328,0.0194033,-0.308407,0.951057,0.0336448,-0.534769,0.844328); -f3(3453,3454,3455,0.16558,-0.509602,0.844328,0.0336448,-0.534769,0.844328,0.0457723,-0.72753,0.684547); -f3(3456,3457,3458,0.119441,-0.626133,0.770513,-0.0400242,-0.636166,0.770513,-0.0267349,-0.424939,0.904827); -f3(3459,3460,3461,0.119441,-0.626133,0.770513,-0.0267349,-0.424939,0.904827,0.0797831,-0.418238,0.904827); -f3(3462,3463,3464,0.16558,-0.509602,0.844328,0.0457723,-0.72753,0.684547,0.225264,-0.69329,0.684547); -f3(3465,3466,3467,-0.164203,0.860785,-0.481754,0.0550238,0.874577,-0.481754,-0.136595,0.716057,-0.684547); -f3(3468,3469,3470,-0.30658,-0.943557,0.125333,-0.531602,-0.83767,-0.125333,-0.531602,-0.83767,0.125333); -f3(3471,3472,3473,0.0351118,0.184062,0.982287,0.181288,0.385257,0.904827,0.0797831,0.169548,0.982287); -f3(3474,3475,3476,-0.30658,-0.943557,0.125333,-0.531602,-0.83767,0.125333,-0.287317,-0.88427,0.368125); -f3(3477,3478,3479,0.0351118,0.184062,0.982287,0.0797831,0.169548,0.982287,-0.0117658,-0.0616783,0.998027); -f3(3480,3481,3482,-0.589748,-0.55381,-0.587785,-0.558579,-0.307081,-0.770513,-0.708947,-0.389747,-0.587785); -f3(3483,3484,3485,-0.589748,-0.55381,-0.587785,-0.708947,-0.389747,-0.587785,-0.814769,-0.447923,-0.368125); -f3(3486,3487,3488,-0.589748,-0.55381,-0.587785,-0.814769,-0.447923,-0.368125,-0.677778,-0.636476,-0.368125); -f3(3489,3490,3491,0.515687,0.623358,0.587785,0.752205,0.546509,0.368125,0.654508,0.475528,0.587785); -f3(3492,3493,3494,-0.181494,-0.0465998,-0.982287,-0.425779,0,-0.904827,-0.412403,-0.105887,-0.904827); -f3(3495,3496,3497,0.515687,0.623358,0.587785,0.654508,0.475528,0.587785,0.406309,0.491144,0.770513); -f3(3498,3499,3500,-0.181494,-0.0465998,-0.982287,-0.187381,0,-0.982287,-0.425779,0,-0.904827); -f3(3501,3502,3503,-0.869397,0.10983,0.481754,-0.814769,0.32259,0.481754,-0.900566,0.356559,0.24869); -f3(3504,3505,3506,0.922445,0.365222,-0.125333,0.984292,0.124345,-0.125333,0.922445,0.365222,0.125333); -f3(3507,3508,3509,0.922445,0.365222,-0.125333,0.922445,0.116532,-0.368125,0.984292,0.124345,-0.125333); -f3(3510,3511,3512,-0.869397,0.10983,0.481754,-0.900566,0.356559,0.24869,-0.960946,0.121396,0.24869); -f3(3513,3514,3515,0.632398,-0.0798904,-0.770513,0.39588,-0.15674,-0.904827,0.592662,-0.234651,-0.770513); -f3(3516,3517,3518,-0.25,0.181636,0.951057,-0.196975,0.238102,0.951057,-0.433493,0.314951,0.844328); -f3(3519,3520,3521,0.632398,-0.0798904,-0.770513,0.592662,-0.234651,-0.770513,0.802638,-0.101397,-0.587785); -f3(3522,3523,3524,-0.0507986,0.0369073,-0.998027,-0.0400242,0.0483809,-0.998027,0.151595,-0.11014,-0.982287); -f3(3525,3526,3527,-0.0507986,0.0369073,-0.998027,-0.196975,0.238102,-0.951057,-0.0400242,0.0483809,-0.998027); -f3(3528,3529,3530,0.181288,-0.385257,0.904827,0.0797831,-0.418238,0.904827,0.0797831,-0.169548,0.982287); -f3(3531,3532,3533,-0.31038,0.659591,-0.684547,-0.136595,0.716057,-0.684547,-0.228144,0.484831,-0.844328); -f3(3534,3535,3536,-0.31038,0.659591,-0.684547,-0.164203,0.860785,-0.481754,-0.136595,0.716057,-0.684547); -f3(3537,3538,3539,0.390601,-0.615489,0.684547,0.225264,-0.69329,0.684547,0.270794,-0.833417,0.481754); -f3(3540,3541,3542,-0.0583811,-0.927942,0.368125,-0.287317,-0.88427,0.368125,-0.0507986,-0.807421,0.587785); -f3(3543,3544,3545,-0.0583811,-0.927942,0.368125,-0.30658,-0.943557,0.125333,-0.287317,-0.88427,0.368125); -f3(3546,3547,3548,0.390601,-0.615489,0.684547,0.270794,-0.833417,0.481754,0.469549,-0.73989,0.481754); -f3(3549,3550,3551,0.00394265,-0.0626666,0.998027,-0.057904,-0.303543,0.951057,0.0194033,-0.308407,0.951057); -f3(3552,3553,3554,0.00394265,-0.0626666,0.998027,-0.0117658,-0.0616783,0.998027,-0.057904,-0.303543,0.951057); -f3(3555,3556,3557,0.00394265,-0.0626666,0.998027,0.0351118,0.184062,0.982287,-0.0117658,-0.0616783,0.998027); -f3(3558,3559,3560,-0.498199,-0.785036,-0.368125,-0.677778,-0.636476,-0.368125,-0.72322,-0.679149,-0.125333); -f3(3561,3562,3563,0.271402,0.576758,0.770513,0.406309,0.491144,0.770513,0.271402,0.328069,0.904827); -f3(3564,3565,3566,-0.498199,-0.785036,-0.368125,-0.72322,-0.679149,-0.125333,-0.531602,-0.83767,-0.125333); -f3(3567,3568,3569,0.271402,0.576758,0.770513,0.271402,0.328069,0.904827,0.181288,0.385257,0.904827); -f3(3570,3571,3572,0.271402,0.576758,0.770513,0.515687,0.623358,0.587785,0.406309,0.491144,0.770513); -f3(3573,3574,3575,-0.373113,-0.205121,-0.904827,-0.412403,-0.105887,-0.904827,-0.558579,-0.307081,-0.770513); -f3(3576,3577,3578,0.802638,0.58315,0.125333,0.922445,0.365222,-0.125333,0.922445,0.365222,0.125333); -f3(3579,3580,3581,-0.960946,-0.121396,0.24869,-0.960946,0.121396,0.24869,-0.992115,0.125333,0); -f3(3582,3583,3584,-0.960946,-0.121396,0.24869,-0.992115,0.125333,0,-0.992115,-0.125333,0); -f3(3585,3586,3587,0.802638,0.58315,0.125333,0.922445,0.365222,0.125333,0.752205,0.546509,0.368125); -f3(3588,3589,3590,-0.498199,0.197251,0.844328,-0.589748,0.428477,0.684547,-0.677778,0.268351,0.684547); -f3(3591,3592,3593,0.802638,0.101397,-0.587785,0.802638,-0.101397,-0.587785,0.922445,-0.116532,-0.368125); -f3(3594,3595,3596,0.802638,0.101397,-0.587785,0.922445,-0.116532,-0.368125,0.922445,0.116532,-0.368125); -f3(3597,3598,3599,-0.498199,0.197251,0.844328,-0.25,0.181636,0.951057,-0.433493,0.314951,0.844328); -f3(3600,3601,3602,-0.498199,0.197251,0.844328,-0.433493,0.314951,0.844328,-0.589748,0.428477,0.684547); -f3(3603,3604,3605,0.802638,0.101397,-0.587785,0.632398,-0.0798904,-0.770513,0.802638,-0.101397,-0.587785); -f3(3606,3607,3608,0.174223,-0.0689797,-0.982287,0.151595,-0.11014,-0.982287,0.344463,-0.250267,-0.904827); -f3(3609,3610,3611,0.119441,-0.14438,0.982287,0.181288,-0.385257,0.904827,0.0797831,-0.169548,0.982287); -f3(3612,3613,3614,0.174223,-0.0689797,-0.982287,0.344463,-0.250267,-0.904827,0.39588,-0.15674,-0.904827); -f3(3615,3616,3617,0.174223,-0.0689797,-0.982287,-0.0507986,0.0369073,-0.998027,0.151595,-0.11014,-0.982287); -f3(3618,3619,3620,-0.341549,0.412862,-0.844328,-0.131573,0.279607,-0.951057,-0.196975,0.238102,-0.951057); -f3(3621,3622,3623,0.119441,-0.14438,0.982287,0.0797831,-0.169548,0.982287,-0.0400242,0.0483809,0.998027); -f3(3624,3625,3626,-0.341549,0.412862,-0.844328,-0.228144,0.484831,-0.844328,-0.131573,0.279607,-0.951057); -f3(3627,3628,3629,-0.341549,0.412862,-0.844328,-0.31038,0.659591,-0.684547,-0.228144,0.484831,-0.844328); -f3(3630,3631,3632,0.151595,-0.794687,0.587785,-0.0583811,-0.927942,0.368125,-0.0507986,-0.807421,0.587785); -f3(3633,3634,3635,0.151595,-0.794687,0.587785,-0.0507986,-0.807421,0.587785,0.119441,-0.626133,0.770513); -f3(3636,3637,3638,0.6388,-0.599873,0.481754,0.469549,-0.73989,0.481754,0.518993,-0.817802,0.24869); -f3(3639,3640,3641,0.6388,-0.599873,0.481754,0.518993,-0.817802,0.24869,0.706067,-0.663041,0.24869); -f3(3642,3643,3644,-0.30658,-0.943557,-0.125333,-0.498199,-0.785036,-0.368125,-0.531602,-0.83767,-0.125333); -f3(3645,3646,3647,-0.30658,-0.943557,-0.125333,-0.531602,-0.83767,-0.125333,-0.30658,-0.943557,0.125333); -f3(3648,3649,3650,0.0954915,-0.293893,0.951057,0.0194033,-0.308407,0.951057,0.16558,-0.509602,0.844328); -f3(3651,3652,3653,-0.181494,0.951427,-0.24869,-0.187381,0.982287,0,0.0627905,0.998027,-0); -f3(3654,3655,3656,-0.464662,-0.436347,-0.770513,-0.373113,-0.205121,-0.904827,-0.558579,-0.307081,-0.770513); -f3(3657,3658,3659,-0.181494,0.951427,-0.24869,0.0608178,0.966672,-0.24869,0.0550238,0.874577,-0.481754); -f3(3660,3661,3662,-0.181494,0.951427,-0.24869,0.0627905,0.998027,-0,0.0608178,0.966672,-0.24869); -f3(3663,3664,3665,-0.464662,-0.436347,-0.770513,-0.558579,-0.307081,-0.770513,-0.589748,-0.55381,-0.587785); -f3(3666,3667,3668,-0.181494,0.951427,-0.24869,0.0550238,0.874577,-0.481754,-0.164203,0.860785,-0.481754); -f3(3669,3670,3671,0.0608178,0.0156154,-0.998027,-0.187381,0,-0.982287,-0.181494,-0.0465998,-0.982287); -f3(3672,3673,3674,0.0797831,0.418238,0.904827,0.181288,0.385257,0.904827,0.0351118,0.184062,0.982287); -f3(3675,3676,3677,0.0608178,0.0156154,-0.998027,0.0627905,0,-0.998027,-0.187381,0,-0.982287); -f3(3678,3679,3680,0.0608178,0.0156154,-0.998027,0.309017,0,-0.951057,0.0627905,0,-0.998027); -f3(3681,3682,3683,-0.72322,0.091364,0.684547,-0.677778,0.268351,0.684547,-0.814769,0.32259,0.481754); -f3(3684,3685,3686,0.592662,0.716405,0.368125,0.802638,0.58315,0.125333,0.752205,0.546509,0.368125); -f3(3687,3688,3689,-0.72322,0.091364,0.684547,-0.814769,0.32259,0.481754,-0.869397,0.10983,0.481754); -f3(3690,3691,3692,0.592662,0.716405,0.368125,0.752205,0.546509,0.368125,0.515687,0.623358,0.587785); -f3(3693,3694,3695,-0.0507986,0.0369073,0.998027,-0.0400242,0.0483809,0.998027,-0.196975,0.238102,0.951057); -f3(3696,3697,3698,-0.0507986,0.0369073,0.998027,-0.196975,0.238102,0.951057,-0.25,0.181636,0.951057); -f3(3699,3700,3701,0.864484,0.342274,-0.368125,0.922445,0.116532,-0.368125,0.922445,0.365222,-0.125333); -f3(3702,3703,3704,-0.0507986,0.0369073,0.998027,0.119441,-0.14438,0.982287,-0.0400242,0.0483809,0.998027); -f3(3705,3706,3707,0.422422,-0.0533643,-0.904827,0.39588,-0.15674,-0.904827,0.632398,-0.0798904,-0.770513); -f3(3708,3709,3710,0.271402,-0.576758,0.770513,0.0797831,-0.418238,0.904827,0.181288,-0.385257,0.904827); -f3(3711,3712,3713,0.271402,-0.576758,0.770513,0.119441,-0.626133,0.770513,0.0797831,-0.418238,0.904827); -f3(3714,3715,3716,0.271402,-0.576758,0.770513,0.151595,-0.794687,0.587785,0.119441,-0.626133,0.770513); -f3(3717,3718,3719,-0.25,0.181636,-0.951057,-0.196975,0.238102,-0.951057,-0.0507986,0.0369073,-0.998027); -f3(3720,3721,3722,-0.0622954,-0.990157,0.125333,-0.30658,-0.943557,0.125333,-0.0583811,-0.927942,0.368125); -f3(3723,3724,3725,0.848776,-0.466619,0.24869,0.706067,-0.663041,0.24869,0.728969,-0.684547,0); -f3(3726,3727,3728,-0.0622954,-0.990157,0.125333,-0.30658,-0.943557,-0.125333,-0.30658,-0.943557,0.125333); -f3(3729,3730,3731,0.848776,-0.466619,0.24869,0.728969,-0.684547,0,0.876307,-0.481754,0); -f3(3732,3733,3734,0.848776,-0.466619,0.24869,0.876307,-0.481754,0,0.968583,-0.24869,0); -f3(3735,3736,3737,-0.433493,-0.683076,-0.587785,-0.589748,-0.55381,-0.587785,-0.677778,-0.636476,-0.368125); -f3(3738,3739,3740,0.28711,-0.452414,0.844328,0.0954915,-0.293893,0.951057,0.16558,-0.509602,0.844328); -f3(3741,3742,3743,-0.433493,-0.683076,-0.587785,-0.677778,-0.636476,-0.368125,-0.498199,-0.785036,-0.368125); -f3(3744,3745,3746,0.28711,-0.452414,0.844328,0.225264,-0.69329,0.684547,0.390601,-0.615489,0.684547); -f3(3747,3748,3749,0.28711,-0.452414,0.844328,0.16558,-0.509602,0.844328,0.225264,-0.69329,0.684547); +v(9.87366,12.5,75); +v(4.8717,12.5,87.5); +v(0,0,100); +v(9.87366,12.5,25); +v(4.8717,12.5,12.5); +v(20.3187,25,25); +v(9.87366,12.5,25); +v(0,0,0); +v(4.8717,12.5,12.5); +v(9.87366,12.5,25); +v(20.3187,25,25); +v(31.5573,25,50); +v(4.53739,15.625,90.625); +v(0,0,100); +v(4.8717,12.5,87.5); +v(4.53739,15.625,90.625); +v(13.6862,37.5,87.5); +v(0,0,100); +v(13.4261,16.6667,75); +v(31.5573,25,50); +v(20.3187,25,75); +v(8.76051,18.75,85.4167); +v(4.53739,15.625,90.625); +v(4.8717,12.5,87.5); +v(8.76051,18.75,85.4167); +v(4.8717,12.5,87.5); +v(9.87366,12.5,75); +v(8.76051,18.75,85.4167); +v(13.6862,37.5,87.5); +v(4.53739,15.625,90.625); +v(8.76051,18.75,85.4167); +v(13.4261,16.6667,75); +v(20.3187,25,75); +v(8.76051,18.75,85.4167); +v(9.87366,12.5,75); +v(13.4261,16.6667,75); +v(8.76051,18.75,85.4167); +v(20.3187,25,75); +v(18.5437,31.25,81.25); +v(8.76051,18.75,85.4167); +v(18.5437,31.25,81.25); +v(13.6862,37.5,87.5); +v(13.6862,37.5,12.5); +v(20.3187,25,25); +v(4.8717,12.5,12.5); +v(13.6862,37.5,12.5); +v(4.8717,12.5,12.5); +v(0,0,0); +v(13.6862,37.5,12.5); +v(0,0,0); +v(13.6862,62.5,12.5); +v(13.6862,37.5,12.5); +v(40.1805,37.5,37.5); +v(20.3187,25,25); +v(13.6862,37.5,12.5); +v(31.5573,50,25); +v(40.1805,37.5,37.5); +v(13.6862,37.5,12.5); +v(13.6862,62.5,12.5); +v(31.5573,50,25); +v(7.1509,93.75,50); +v(0,100,0); +v(0,100,100); +v(7.1509,93.75,50); +v(3.55938,93.75,18.75); +v(0,100,0); +v(7.1509,93.75,50); +v(0,100,100); +v(3.55938,93.75,81.25); +v(7.1509,93.75,50); +v(13.6862,87.5,62.5); +v(31.5573,75,50); +v(7.1509,93.75,50); +v(31.5573,75,50); +v(13.6862,87.5,37.5); +v(7.1509,93.75,50); +v(3.55938,93.75,81.25); +v(13.6862,87.5,62.5); +v(13.6862,37.5,87.5); +v(0,100,100); +v(0,0,100); +v(7.1509,93.75,50); +v(13.6862,87.5,37.5); +v(3.55938,93.75,18.75); +v(15.122,12.5,50); +v(0,0,100); +v(0,0,0); +v(15.122,12.5,50); +v(9.87366,12.5,75); +v(0,0,100); +v(15.122,12.5,50); +v(9.87366,12.5,25); +v(31.5573,25,50); +v(15.122,12.5,50); +v(0,0,0); +v(9.87366,12.5,25); +v(40.1805,37.5,62.5); +v(20.3187,25,75); +v(31.5573,25,50); +v(15.122,12.5,50); +v(13.4261,16.6667,75); +v(9.87366,12.5,75); +v(15.122,12.5,50); +v(31.5573,25,50); +v(13.4261,16.6667,75); +v(40.1805,37.5,62.5); +v(18.5437,31.25,81.25); +v(20.3187,25,75); +v(40.1805,37.5,37.5); +v(31.5573,25,50); +v(20.3187,25,25); +v(37.8639,43.75,68.75); +v(18.5437,31.25,81.25); +v(40.1805,37.5,62.5); +v(31.5573,50,75); +v(13.6862,37.5,87.5); +v(18.5437,31.25,81.25); +v(31.5573,50,75); +v(18.5437,31.25,81.25); +v(37.8639,43.75,68.75); +v(49.9929,50,50); +v(40.1805,37.5,62.5); +v(31.5573,25,50); +v(49.9929,50,50); +v(31.5573,25,50); +v(40.1805,37.5,37.5); +v(49.9929,50,50); +v(37.8639,43.75,68.75); +v(40.1805,37.5,62.5); +v(47.3189,56.25,56.25); +v(37.8639,43.75,68.75); +v(49.9929,50,50); +v(47.3189,56.25,43.75); +v(49.9929,50,50); +v(40.1805,37.5,37.5); +v(47.3189,56.25,43.75); +v(40.1805,37.5,37.5); +v(31.5573,50,25); +v(47.3189,56.25,43.75); +v(47.3189,56.25,56.25); +v(49.9929,50,50); +v(13.6862,62.5,87.5); +v(0,100,100); +v(13.6862,37.5,87.5); +v(13.6862,62.5,87.5); +v(13.6862,37.5,87.5); +v(31.5573,50,75); +v(40.1805,62.5,62.5); +v(31.5573,50,75); +v(37.8639,43.75,68.75); +v(40.1805,62.5,62.5); +v(37.8639,43.75,68.75); +v(47.3189,56.25,56.25); +v(44.7577,62.5,50); +v(47.3189,56.25,56.25); +v(47.3189,56.25,43.75); +v(40.1805,62.5,37.5); +v(47.3189,56.25,43.75); +v(31.5573,50,25); +v(40.1805,62.5,37.5); +v(44.7577,62.5,50); +v(47.3189,56.25,43.75); +v(13.6862,62.5,12.5); +v(0,0,0); +v(0,100,0); +v(37.8639,68.75,56.25); +v(40.1805,62.5,62.5); +v(47.3189,56.25,56.25); +v(37.8639,68.75,56.25); +v(47.3189,56.25,56.25); +v(44.7577,62.5,50); +v(37.8639,68.75,43.75); +v(44.7577,62.5,50); +v(40.1805,62.5,37.5); +v(20.3187,75,75); +v(40.1805,62.5,62.5); +v(37.8639,68.75,56.25); +v(20.3187,75,75); +v(13.6862,62.5,87.5); +v(31.5573,50,75); +v(20.3187,75,75); +v(31.5573,50,75); +v(40.1805,62.5,62.5); +v(31.5573,75,50); +v(37.8639,68.75,56.25); +v(44.7577,62.5,50); +v(31.5573,75,50); +v(44.7577,62.5,50); +v(37.8639,68.75,43.75); +v(20.3187,75,25); +v(40.1805,62.5,37.5); +v(31.5573,50,25); +v(20.3187,75,25); +v(31.5573,50,25); +v(13.6862,62.5,12.5); +v(20.3187,75,25); +v(37.8639,68.75,43.75); +v(40.1805,62.5,37.5); +v(18.5437,81.25,68.75); +v(20.3187,75,75); +v(37.8639,68.75,56.25); +v(18.5437,81.25,68.75); +v(37.8639,68.75,56.25); +v(31.5573,75,50); +v(18.5437,81.25,31.25); +v(37.8639,68.75,43.75); +v(20.3187,75,25); +v(4.8717,87.5,87.5); +v(0,100,100); +v(13.6862,62.5,87.5); +v(4.8717,87.5,87.5); +v(13.6862,62.5,87.5); +v(20.3187,75,75); +v(4.8717,87.5,87.5); +v(20.3187,75,75); +v(18.5437,81.25,68.75); +v(13.6862,87.5,62.5); +v(18.5437,81.25,68.75); +v(31.5573,75,50); +v(13.6862,87.5,37.5); +v(31.5573,75,50); +v(37.8639,68.75,43.75); +v(13.6862,87.5,37.5); +v(37.8639,68.75,43.75); +v(18.5437,81.25,31.25); +v(4.8717,87.5,12.5); +v(13.6862,62.5,12.5); +v(0,100,0); +v(4.8717,87.5,12.5); +v(20.3187,75,25); +v(13.6862,62.5,12.5); +v(4.8717,87.5,12.5); +v(18.5437,81.25,31.25); +v(20.3187,75,25); +v(3.55938,93.75,81.25); +v(0,100,100); +v(4.8717,87.5,87.5); +v(3.55938,93.75,81.25); +v(4.8717,87.5,87.5); +v(18.5437,81.25,68.75); +v(3.55938,93.75,81.25); +v(18.5437,81.25,68.75); +v(13.6862,87.5,62.5); +v(3.55938,93.75,18.75); +v(4.8717,87.5,12.5); +v(0,100,0); +v(3.55938,93.75,18.75); +v(13.6862,87.5,37.5); +v(18.5437,81.25,31.25); +v(3.55938,93.75,18.75); +v(18.5437,81.25,31.25); +v(4.8717,87.5,12.5); +f3(0,1,2,0.733856,-0.622456,0.272037,0.864298,-0.35566,0.35566,1,-0.000119106,0.000119106); +f3(3,4,5,0.733856,-0.622456,-0.272037,0.864298,-0.35566,-0.35566,0.670005,-0.524925,-0.524925); +f3(6,7,8,0.733856,-0.622456,-0.272037,1,-0.000119106,-0.000119106,0.864298,-0.35566,-0.35566); +f3(9,10,11,0.733856,-0.622456,-0.272037,0.670005,-0.524925,-0.524925,0.624605,-0.780941,1.69202e-13); +f3(12,13,14,0.85916,-0.258781,0.441449,1,-0.000119106,0.000119106,0.864298,-0.35566,0.35566); +f3(15,16,17,0.85916,-0.258781,0.441449,0.637496,-0.141941,0.757266,1,-0.000119106,0.000119106); +f3(18,19,20,0.709532,-0.605086,0.361158,0.624605,-0.780941,1.69202e-13,0.670005,-0.524925,0.524925); +f3(21,22,23,0.782156,-0.374506,0.497973,0.85916,-0.258781,0.441449,0.864298,-0.35566,0.35566); +f3(24,25,26,0.782156,-0.374506,0.497973,0.864298,-0.35566,0.35566,0.733856,-0.622456,0.272037); +f3(27,28,29,0.782156,-0.374506,0.497973,0.637496,-0.141941,0.757266,0.85916,-0.258781,0.441449); +f3(30,31,32,0.782156,-0.374506,0.497973,0.709532,-0.605086,0.361158,0.670005,-0.524925,0.524925); +f3(33,34,35,0.782156,-0.374506,0.497973,0.733856,-0.622456,0.272037,0.709532,-0.605086,0.361158); +f3(36,37,38,0.782156,-0.374506,0.497973,0.670005,-0.524925,0.524925,0.656891,-0.318708,0.683315); +f3(39,40,41,0.782156,-0.374506,0.497973,0.656891,-0.318708,0.683315,0.637496,-0.141941,0.757266); +f3(42,43,44,0.637496,-0.141941,-0.757266,0.670005,-0.524925,-0.524925,0.864298,-0.35566,-0.35566); +f3(45,46,47,0.637496,-0.141941,-0.757266,0.864298,-0.35566,-0.35566,1,-0.000119106,-0.000119106); +f3(48,49,50,0.637496,-0.141941,-0.757266,1,-0.000119106,-0.000119106,0.637496,0.141941,-0.757266); +f3(51,52,53,0.637496,-0.141941,-0.757266,0.710482,-0.497602,-0.497602,0.670005,-0.524925,-0.524925); +f3(54,55,56,0.637496,-0.141941,-0.757266,0.624605,-2.38547e-14,-0.780941,0.710482,-0.497602,-0.497602); +f3(57,58,59,0.637496,-0.141941,-0.757266,0.637496,0.141941,-0.757266,0.624605,-2.38547e-14,-0.780941); +f3(60,61,62,0.633632,0.773635,-1.10023e-13,1,0.000119106,-0.000119106,1,0.000119106,0.000119106); +f3(63,64,65,0.633632,0.773635,-1.10023e-13,0.846072,0.507989,-0.161587,1,0.000119106,-0.000119106); +f3(66,67,68,0.633632,0.773635,-1.10023e-13,1,0.000119106,0.000119106,0.846072,0.507989,0.161587); +f3(69,70,71,0.633632,0.773635,-1.10023e-13,0.637496,0.757266,0.141941,0.624605,0.780941,9.77766e-14); +f3(72,73,74,0.633632,0.773635,-1.10023e-13,0.624605,0.780941,9.77766e-14,0.637496,0.757266,-0.141941); +f3(75,76,77,0.633632,0.773635,-1.10023e-13,0.846072,0.507989,0.161587,0.637496,0.757266,0.141941); +f3(78,79,80,0.637496,-0.141941,0.757266,1,0.000119106,0.000119106,1,-0.000119106,0.000119106); +f3(81,82,83,0.633632,0.773635,-1.10023e-13,0.637496,0.757266,-0.141941,0.846072,0.507989,-0.161587); +f3(84,85,86,0.604693,-0.796458,8.52608e-14,1,-0.000119106,0.000119106,1,-0.000119106,-0.000119106); +f3(87,88,89,0.604693,-0.796458,8.52608e-14,0.733856,-0.622456,0.272037,1,-0.000119106,0.000119106); +f3(90,91,92,0.604693,-0.796458,8.52608e-14,0.733856,-0.622456,-0.272037,0.624605,-0.780941,1.69202e-13); +f3(93,94,95,0.604693,-0.796458,8.52608e-14,1,-0.000119106,-0.000119106,0.733856,-0.622456,-0.272037); +f3(96,97,98,0.710482,-0.497602,0.497602,0.670005,-0.524925,0.524925,0.624605,-0.780941,1.69202e-13); +f3(99,100,101,0.604693,-0.796458,8.52608e-14,0.709532,-0.605086,0.361158,0.733856,-0.622456,0.272037); +f3(102,103,104,0.604693,-0.796458,8.52608e-14,0.624605,-0.780941,1.69202e-13,0.709532,-0.605086,0.361158); +f3(105,106,107,0.710482,-0.497602,0.497602,0.656891,-0.318708,0.683315,0.670005,-0.524925,0.524925); +f3(108,109,110,0.710482,-0.497602,-0.497602,0.624605,-0.780941,1.69202e-13,0.670005,-0.524925,-0.524925); +f3(111,112,113,0.676654,-0.214931,0.704233,0.656891,-0.318708,0.683315,0.710482,-0.497602,0.497602); +f3(114,115,116,0.624605,-1.23642e-13,0.780941,0.637496,-0.141941,0.757266,0.656891,-0.318708,0.683315); +f3(117,118,119,0.624605,-1.23642e-13,0.780941,0.656891,-0.318708,0.683315,0.676654,-0.214931,0.704233); +f3(120,121,122,1,-6.61714e-13,5.23624e-13,0.710482,-0.497602,0.497602,0.624605,-0.780941,1.69202e-13); +f3(123,124,125,1,-6.61714e-13,5.23624e-13,0.624605,-0.780941,1.69202e-13,0.710482,-0.497602,-0.497602); +f3(126,127,128,1,-6.61714e-13,5.23624e-13,0.676654,-0.214931,0.704233,0.710482,-0.497602,0.497602); +f3(129,130,131,0.862587,0.357731,0.357731,0.676654,-0.214931,0.704233,1,-6.61714e-13,5.23624e-13); +f3(132,133,134,0.862587,0.357731,-0.357731,1,-6.61714e-13,5.23624e-13,0.710482,-0.497602,-0.497602); +f3(135,136,137,0.862587,0.357731,-0.357731,0.710482,-0.497602,-0.497602,0.624605,-2.38547e-14,-0.780941); +f3(138,139,140,0.862587,0.357731,-0.357731,0.862587,0.357731,0.357731,1,-6.61714e-13,5.23624e-13); +f3(141,142,143,0.637496,0.141941,0.757266,1,0.000119106,0.000119106,0.637496,-0.141941,0.757266); +f3(144,145,146,0.637496,0.141941,0.757266,0.637496,-0.141941,0.757266,0.624605,-1.23642e-13,0.780941); +f3(147,148,149,0.710482,0.497602,0.497602,0.624605,-1.23642e-13,0.780941,0.676654,-0.214931,0.704233); +f3(150,151,152,0.710482,0.497602,0.497602,0.676654,-0.214931,0.704233,0.862587,0.357731,0.357731); +f3(153,154,155,0.782164,0.623073,3.21907e-13,0.862587,0.357731,0.357731,0.862587,0.357731,-0.357731); +f3(156,157,158,0.710482,0.497602,-0.497602,0.862587,0.357731,-0.357731,0.624605,-2.38547e-14,-0.780941); +f3(159,160,161,0.710482,0.497602,-0.497602,0.782164,0.623073,3.21907e-13,0.862587,0.357731,-0.357731); +f3(162,163,164,0.637496,0.141941,-0.757266,1,-0.000119106,-0.000119106,1,0.000119106,-0.000119106); +f3(165,166,167,0.676654,0.704233,0.214931,0.710482,0.497602,0.497602,0.862587,0.357731,0.357731); +f3(168,169,170,0.676654,0.704233,0.214931,0.862587,0.357731,0.357731,0.782164,0.623073,3.21907e-13); +f3(171,172,173,0.676654,0.704233,-0.214931,0.782164,0.623073,3.21907e-13,0.710482,0.497602,-0.497602); +f3(174,175,176,0.670005,0.524925,0.524925,0.710482,0.497602,0.497602,0.676654,0.704233,0.214931); +f3(177,178,179,0.670005,0.524925,0.524925,0.637496,0.141941,0.757266,0.624605,-1.23642e-13,0.780941); +f3(180,181,182,0.670005,0.524925,0.524925,0.624605,-1.23642e-13,0.780941,0.710482,0.497602,0.497602); +f3(183,184,185,0.624605,0.780941,9.77766e-14,0.676654,0.704233,0.214931,0.782164,0.623073,3.21907e-13); +f3(186,187,188,0.624605,0.780941,9.77766e-14,0.782164,0.623073,3.21907e-13,0.676654,0.704233,-0.214931); +f3(189,190,191,0.670005,0.524925,-0.524925,0.710482,0.497602,-0.497602,0.624605,-2.38547e-14,-0.780941); +f3(192,193,194,0.670005,0.524925,-0.524925,0.624605,-2.38547e-14,-0.780941,0.637496,0.141941,-0.757266); +f3(195,196,197,0.670005,0.524925,-0.524925,0.676654,0.704233,-0.214931,0.710482,0.497602,-0.497602); +f3(198,199,200,0.656891,0.683315,0.318708,0.670005,0.524925,0.524925,0.676654,0.704233,0.214931); +f3(201,202,203,0.656891,0.683315,0.318708,0.676654,0.704233,0.214931,0.624605,0.780941,9.77766e-14); +f3(204,205,206,0.656891,0.683315,-0.318708,0.676654,0.704233,-0.214931,0.670005,0.524925,-0.524925); +f3(207,208,209,0.864298,0.35566,0.35566,1,0.000119106,0.000119106,0.637496,0.141941,0.757266); +f3(210,211,212,0.864298,0.35566,0.35566,0.637496,0.141941,0.757266,0.670005,0.524925,0.524925); +f3(213,214,215,0.864298,0.35566,0.35566,0.670005,0.524925,0.524925,0.656891,0.683315,0.318708); +f3(216,217,218,0.637496,0.757266,0.141941,0.656891,0.683315,0.318708,0.624605,0.780941,9.77766e-14); +f3(219,220,221,0.637496,0.757266,-0.141941,0.624605,0.780941,9.77766e-14,0.676654,0.704233,-0.214931); +f3(222,223,224,0.637496,0.757266,-0.141941,0.676654,0.704233,-0.214931,0.656891,0.683315,-0.318708); +f3(225,226,227,0.864298,0.35566,-0.35566,0.637496,0.141941,-0.757266,1,0.000119106,-0.000119106); +f3(228,229,230,0.864298,0.35566,-0.35566,0.670005,0.524925,-0.524925,0.637496,0.141941,-0.757266); +f3(231,232,233,0.864298,0.35566,-0.35566,0.656891,0.683315,-0.318708,0.670005,0.524925,-0.524925); +f3(234,235,236,0.846072,0.507989,0.161587,1,0.000119106,0.000119106,0.864298,0.35566,0.35566); +f3(237,238,239,0.846072,0.507989,0.161587,0.864298,0.35566,0.35566,0.656891,0.683315,0.318708); +f3(240,241,242,0.846072,0.507989,0.161587,0.656891,0.683315,0.318708,0.637496,0.757266,0.141941); +f3(243,244,245,0.846072,0.507989,-0.161587,0.864298,0.35566,-0.35566,1,0.000119106,-0.000119106); +f3(246,247,248,0.846072,0.507989,-0.161587,0.637496,0.757266,-0.141941,0.656891,0.683315,-0.318708); +f3(249,250,251,0.846072,0.507989,-0.161587,0.656891,0.683315,-0.318708,0.864298,0.35566,-0.35566); function v( x, y, z ) { scope.vertices.push(new THREE.Vertex(new THREE.Vector3(x,y,z))); } diff --git a/src/examples/WebGl/webgl_geomplate.py b/src/examples/WebGl/webgl_geomplate.py index 3de876d53..3548a42e6 100644 --- a/src/examples/WebGl/webgl_geomplate.py +++ b/src/examples/WebGl/webgl_geomplate.py @@ -190,7 +190,8 @@ def build_curve_network(event=None): ''' print 'Importing IGES file...', pth = os.path.dirname(os.path.abspath(__file__)) - pth = os.path.abspath(os.path.join(pth, '../../data/IGES/curve_geom_plate.igs')) + pth = os.path.abspath(os.path.join(pth, '../data/IGES/curve_geom_plate.igs')) + import ipdb; ipdb.set_trace() iges = IGESImporter(pth) iges.read_file() print 'done.' From a51608bc268e35d0a095ace16d9db8f9eddfc72f Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 17:26:00 +0200 Subject: [PATCH 12/29] the topology module got a lot of love and is now compatible with KBE, such that KBE types are returned. also, its now possible to ignore the direction of the edges for example, which is very practical --- src/addons/Utils/Topology.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addons/Utils/Topology.py b/src/addons/Utils/Topology.py index 6502e0bc4..c082e622d 100644 --- a/src/addons/Utils/Topology.py +++ b/src/addons/Utils/Topology.py @@ -1 +1 @@ -# -*- coding: iso-8859-1 -*- #!/usr/bin/env python ##Copyright 2008-2011 Jelle Feringa (jelleferinga@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC 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 3 of the License, or ##(at your option) any later version. ## ##pythonOCC 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 pythonOCC. If not, see . ''' TODO: Hide WireExplorer... BRepTools.Map3DEdges() History: 20-01-2009: initial version 23-03-2009: completed and updated for modular pythonOCC build 23-04-2009: fixed a reference issue ( fixed using ReInit ) ''' from OCC.TopAbs import * from OCC.TopExp import * from OCC.TopoDS import * from OCC.TopTools import * from OCC.BRepTools import * from OCC.BRep import * import sys, itertools __all__ = ['Topo', 'WireExplorer'] class WireExplorer(object): ''' ''' def __init__(self, wire): assert isinstance(wire, TopoDS_Wire), 'not a TopoDS_Wire' self.wire = wire self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _reinitialize(self): self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _loop_topo(self, edges=True): if self.done: self._reinitialize() topologyType = TopoDS_edge if edges else TopoDS_vertex seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.wire_explorer.More(): # loop edges if edges: current_item = self.wire_explorer.Current() # loop vertices else: current_item = self.wire_explorer.CurrentVertex() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.wire_explorer.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = topologyType(occ_iterator.Value()) seq.append(topo_to_add) occ_iterator.Next() return iter(seq) self.done = True def ordered_edges(self): return self._loop_topo(edges=True) def ordered_vertices(self): return self._loop_topo(edges=False) class Topo(object): ''' sketch for a pythonic topology wrapper note that `myShape` should be self, which is in return a occ.TopoShape with this ''' def __init__(self, myShape): self.myShape = myShape def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=None): ''' this could be a faces generator for a python TopoShape class that way you can just do: for face in srf.faces: processFace(face) ''' topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid} assert topologyType in topoTypes.keys(), '%s not one of %s' %( topologyType, topoTypes.keys() ) self.topExp = TopExp_Explorer() # use self.myShape if nothing is specified if topologicalEntity is None and topologyTypeToAvoid is None: self.topExp.Init(self.myShape, topologyType) elif topologicalEntity is None and topologyTypeToAvoid is not None: self.topExp.Init(self.myShape, topologyType, topologyTypeToAvoid) elif topologyTypeToAvoid is None: self.topExp.Init(topologicalEntity, topologyType ) elif topologyTypeToAvoid: self.topExp.Init(topologicalEntity, topologyType, topologyTypeToAvoid) topo_set = set() seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.topExp.More(): current_item = self.topExp.Current() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.topExp.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = topoTypes[topologyType](occ_iterator.Value()) seq.append(topo_to_add) occ_iterator.Next() return iter(seq) def faces(self): ''' loops over all faces ''' return self._loop_topo(TopAbs_FACE) def _number_of_topo(self, iterable): n = 0 for i in iterable: n+=1 return n def number_of_faces(self): return self._number_of_topo(self.faces()) def vertices(self): ''' loops over all vertices ''' return self._loop_topo(TopAbs_VERTEX) def number_of_vertices(self): return self._number_of_topo(self.vertices()) def edges(self): ''' loops over all edges ''' return self._loop_topo(TopAbs_EDGE) def number_of_edges(self): return self._number_of_topo(self.edges()) def wires(self): ''' loops over all wires ''' return self._loop_topo(TopAbs_WIRE) def number_of_wires(self): return self._number_of_topo(self.wires()) def shells(self): ''' loops over all shells ''' return self._loop_topo(TopAbs_SHELL, None) def number_of_shells(self): return self._number_of_topo(self.shells()) def solids(self): ''' loops over all solids ''' return self._loop_topo(TopAbs_SOLID, None) def number_of_solids(self): return self._number_of_topo(self.solids()) def comp_solids(self): ''' loops over all compound solids ''' return self._loop_topo(TopAbs_COMPSOLID) def number_of_comp_solids(self): return self._number_of_topo(self.comp_solids()) def compounds(self): ''' loops over all compounds ''' return self._loop_topo(TopAbs_COMPOUND) def number_of_compounds(self): return self._number_of_topo(self.compounds()) def ordered_vertices_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_vertices() def number_of_ordered_vertices_from_wire(self, wire): return self._number_of_topo(self.ordered_vertices_from_wire(wire)) def ordered_edges_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_edges() def number_of_ordered_edges_from_wire(self, wire): return self._number_of_topo(self.ordered_edges_from_wire(wire)) def _map_shapes_and_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): ''' using the same method @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): yield None topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid} topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_entity = topoTypes[topoTypeB](topology_iterator.Value()) # return the entity if not in set # to assure we're not returning entities several times if not topo_entity in topo_set: yield topo_entity topo_set.add(topo_entity) topology_iterator.Next() def _number_shapes_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): '''returns the number of shape ancestors If you want to know how many edges a faces has: _number_shapes_ancestors(self, TopAbs_EDGE, TopAbs_FACE, edg) will return the number of edges a faces has @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): return None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_set.add(topology_iterator.Value()) topology_iterator.Next() return len(topo_set) #=============================================================================== # EDGE <-> FACE #=============================================================================== def faces_from_edge(self, edge): return self._map_shapes_and_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def number_of_faces_from_edge(self, edge): return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def edges_from_face(self, face): return self._loop_topo(TopAbs_EDGE, face) def number_of_edges_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, face): cnt += 1 return cnt #=============================================================================== # VERTEX <-> EDGE #=============================================================================== def vertices_from_edge(self, edg): return self._loop_topo(TopAbs_VERTEX, edg) def number_of_vertices_from_edge(self, edg): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, edg): cnt += 1 return cnt def edges_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_EDGE,vertex) def number_of_edges_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_EDGE,vertex) #=============================================================================== # WIRE <-> EDGE #=============================================================================== def edges_from_wire(self, wire): return self._loop_topo(TopAbs_EDGE, wire) def number_of_edges_from_wire(self, wire): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, wire): cnt += 1 return cnt def wires_from_edge(self, edg): return self._map_shapes_and_ancestors(TopAbs_EDGE, TopAbs_WIRE, edg) def number_of_wires_from_edge(self, edg): return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_WIRE, edg) #=============================================================================== # WIRE <-> FACE #=============================================================================== def wires_from_face(self, face): return self._loop_topo(TopAbs_WIRE, face) def number_of_wires_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_WIRE, face): cnt += 1 return cnt def faces_from_wire(self, wire): return self._map_shapes_and_ancestors(TopAbs_WIRE, TopAbs_FACE, wire) def number_of_faces_from_wires(self, wire): return self._number_shapes_ancestors(TopAbs_WIRE,TopAbs_FACE, wire) #=============================================================================== # VERTEX <-> FACE #=============================================================================== def faces_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def number_of_faces_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def vertices_from_face(self, face): return self._loop_topo(TopAbs_VERTEX, face) def number_of_vertices_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, face): cnt += 1 return cnt #=============================================================================== # FACE <-> SOLID #=============================================================================== def solids_from_face(self, face): return self._map_shapes_and_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def number_of_solids_from_face(self, face): return self._number_shapes_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def faces_from_solids(self, solid): return self._loop_topo(TopAbs_FACE, solid) def number_of_faces_from_solids(self, solid): cnt = 0 for i in self._loop_topo(TopAbs_FACE, solid): cnt += 1 return cnt def dumpTopology(shape,level=0): """ Print the details of an object from the top down """ brt = BRep_Tool() s = shape.ShapeType() ts = TopoDS.TopoDS() print print "." * level,shapeTypeString(shape), if s == TopAbs_VERTEX: pnt = brt.Pnt(ts.Vertex(shape)) print "" % (pnt.X(), pnt.Y(), pnt.Z()) it = TopoDS.TopoDS_Iterator(shape) while it.More(): shp = it.Value() it.Next() dumpTopology(shp,level + 1 ) def shapeTypeString(shape): st = shape.ShapeType() s = "?" if st == TopAbs_VERTEX: s = "Vertex" if st == TopAbs_SOLID: s = "Solid" if st == TopAbs_EDGE: s = "Edge" if st == TopAbs_FACE: s = "Face" if st == TopAbs_SHELL: s = "Shell" if st == TopAbs_WIRE: s = "Wire" if st == TopAbs_COMPOUND: s = "Compound." if st == TopAbs_COMPSOLID: s = "Compsolid." return s + ":" + str(shape.HashCode(23232232)) \ No newline at end of file +# -*- coding: iso-8859-1 -*- #!/usr/bin/env python ##Copyright 2008-2011 Jelle Feringa (jelleferinga@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC 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 3 of the License, or ##(at your option) any later version. ## ##pythonOCC 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 pythonOCC. If not, see . ''' TODO: Hide WireExplorer... BRepTools.Map3DEdges() History: 20-01-2009: initial version 23-03-2009: completed and updated for modular pythonOCC build 23-04-2009: fixed a reference issue ( fixed using ReInit ) ''' from OCC.TopAbs import * from OCC.TopExp import * from OCC.TopoDS import * from OCC.TopTools import * from OCC.BRepTools import * from OCC.BRep import * from OCC.KBE.types_lut import topo_lut, shape_lut from OCC.KBE.edge import Edge from OCC.Utils.Construct import vertex2pnt import sys, itertools __all__ = ['Topo', 'WireExplorer'] class WireExplorer(object): ''' ''' def __init__(self, wire, kbe_types=False): assert isinstance(wire, TopoDS_Wire), 'not a TopoDS_Wire' self.kbe_types = kbe_types self.wire = wire self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _reinitialize(self): self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _loop_topo(self, edges=True): if self.done: self._reinitialize() topologyType = TopoDS_edge if edges else TopoDS_vertex seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.wire_explorer.More(): # loop edges if edges: current_item = self.wire_explorer.Current() # loop vertices else: current_item = self.wire_explorer.CurrentVertex() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.wire_explorer.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = topologyType(occ_iterator.Value()) if self.kbe_types and edges: edge = Edge(topo_to_add) seq.append(edge) else: seq.append(topo_to_add) occ_iterator.Next() return iter(seq) self.done = True def ordered_edges(self): return self._loop_topo(edges=True) def ordered_vertices(self): return self._loop_topo(edges=False) class Topo(object): ''' Topology traversal ''' def __init__(self, myShape, kbe_types=False, ignore_orientation=False): """ implements topology traversal from any TopoDS_Shape this class lets you find how various topological entities are connected from one to another find the faces connected to an edge, find the vertices this edge is made from, get all faces connected to a vertex, and find out how many topological elements are connected from a source *note* when traversing TopoDS_Wire entities, its advised to use the specialized ``WireExplorer`` class, which will return the vertices / edges in the expected order :param myShape: the shape which topology will be traversed :param kbe_types: whether to return OCC.KBE topology types KBE types offers a more consistent and pythonic API, since many useful methods are bound to these objects :param ignore_orientation: filter out TopoDS_* entities of similar TShape but different Orientation for instance, a cube has 24 edges, 4 edges for each of 6 faces that results in 48 vertices, while there are only 8 vertices that have a unique geometric coordinate in certain cases ( computing a graph from the topology ) its preferable to return topological entities that share similar geometry, though differ in orientation by setting the ``ignore_orientation`` variable to True, in case of a cube, just 12 edges and only 8 vertices will be returned for further reference see TopoDS_Shape IsEqual / IsSame methods """ self.myShape = myShape self.kbe_types = kbe_types self.ignore_orientation = ignore_orientation self.topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid } if self.kbe_types: from OCC.KBE.vertex import Vertex from OCC.KBE.edge import Edge from OCC.KBE.face import Face from OCC.KBE.solid import Shell, Solid self.kbeTypes = { TopAbs_VERTEX: Vertex, TopAbs_EDGE: Edge, TopAbs_FACE: Face, TopAbs_SHELL: Shell, TopAbs_SOLID: Solid, } def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=None): ''' this could be a faces generator for a python TopoShape class that way you can just do: for face in srf.faces(): processFace(face) ''' topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid} assert topologyType in self.topoTypes.keys(), '%s not one of %s' %( topologyType, self.topoTypes.keys() ) self.topExp = TopExp_Explorer() # use self.myShape if nothing is specified if topologicalEntity is None and topologyTypeToAvoid is None: self.topExp.Init(self.myShape, topologyType) elif topologicalEntity is None and topologyTypeToAvoid is not None: self.topExp.Init(self.myShape, topologyType, topologyTypeToAvoid) elif topologyTypeToAvoid is None: self.topExp.Init(topologicalEntity, topologyType ) elif topologyTypeToAvoid: self.topExp.Init(topologicalEntity, topologyType, topologyTypeToAvoid) topo_set = set() seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.topExp.More(): current_item = self.topExp.Current() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.topExp.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = self.topoTypes[topologyType](occ_iterator.Value()) # return a KBE type if self.kbe_types: if topologyType in self.kbeTypes: seq.append(self.kbeTypes[topologyType](topo_to_add)) # otherwise a plain TopoDS_Shape subclass else: seq.append(topo_to_add) occ_iterator.Next() if self.ignore_orientation: # filter out those entities that share the same TShape # but do *not* share the same orientation filter_orientation_seq = [] for i in seq: _present = False for j in filter_orientation_seq: if i.IsSame(j): _present = True break if _present is False: filter_orientation_seq.append(i) return filter_orientation_seq else: return iter(seq) def faces(self): ''' loops over all faces ''' return self._loop_topo(TopAbs_FACE) def _number_of_topo(self, iterable): n = 0 for i in iterable: n+=1 return n def number_of_faces(self): return self._number_of_topo(self.faces()) def vertices(self): ''' loops over all vertices ''' return self._loop_topo(TopAbs_VERTEX) def number_of_vertices(self): return self._number_of_topo(self.vertices()) def edges(self): ''' loops over all edges ''' return self._loop_topo(TopAbs_EDGE) def number_of_edges(self): return self._number_of_topo(self.edges()) def wires(self): ''' loops over all wires ''' return self._loop_topo(TopAbs_WIRE) def number_of_wires(self): return self._number_of_topo(self.wires()) def shells(self): ''' loops over all shells ''' return self._loop_topo(TopAbs_SHELL, None) def number_of_shells(self): return self._number_of_topo(self.shells()) def solids(self): ''' loops over all solids ''' return self._loop_topo(TopAbs_SOLID, None) def number_of_solids(self): return self._number_of_topo(self.solids()) def comp_solids(self): ''' loops over all compound solids ''' return self._loop_topo(TopAbs_COMPSOLID) def number_of_comp_solids(self): return self._number_of_topo(self.comp_solids()) def compounds(self): ''' loops over all compounds ''' return self._loop_topo(TopAbs_COMPOUND) def number_of_compounds(self): return self._number_of_topo(self.compounds()) def ordered_vertices_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_vertices() def number_of_ordered_vertices_from_wire(self, wire): return self._number_of_topo(self.ordered_vertices_from_wire(wire)) def ordered_edges_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_edges() def number_of_ordered_edges_from_wire(self, wire): return self._number_of_topo(self.ordered_edges_from_wire(wire)) def _map_shapes_and_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): ''' using the same method @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): yield None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_entity = self.topoTypes[topoTypeB](topology_iterator.Value()) if self.kbe_types: if topoTypeB in self.kbeTypes: topo_entity = self.kbeTypes[topoTypeB](topo_entity) else: raise ValueError('none KBE types called') # return the entity if not in set # to assure we're not returning entities several times if not topo_entity in topo_set: if self.ignore_orientation: unique=True for i in topo_set: if i.IsSame(topo_entity): unique=False break if unique: yield topo_entity else: yield topo_entity topo_set.add(topo_entity) topology_iterator.Next() def _number_shapes_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): '''returns the number of shape ancestors If you want to know how many edges a faces has: _number_shapes_ancestors(self, TopAbs_EDGE, TopAbs_FACE, edg) will return the number of edges a faces has @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): return None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_set.add(topology_iterator.Value()) topology_iterator.Next() return len(topo_set) #=============================================================================== # EDGE <-> FACE #=============================================================================== def faces_from_edge(self, edge): """ :param edge: :return: """ return self._map_shapes_and_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def number_of_faces_from_edge(self, edge): """ :param edge: :return: """ return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def edges_from_face(self, face): """ :param face: :return: """ return self._loop_topo(TopAbs_EDGE, face) def number_of_edges_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, face): cnt += 1 return cnt #=============================================================================== # VERTEX <-> EDGE #=============================================================================== def vertices_from_edge(self, edg): return self._loop_topo(TopAbs_VERTEX, edg) def number_of_vertices_from_edge(self, edg): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, edg): cnt += 1 return cnt def edges_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_EDGE,vertex) def number_of_edges_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_EDGE,vertex) #=============================================================================== # WIRE <-> EDGE #=============================================================================== def edges_from_wire(self, wire): return self._loop_topo(TopAbs_EDGE, wire) def number_of_edges_from_wire(self, wire): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, wire): cnt += 1 return cnt def wires_from_edge(self, edg): return self._map_shapes_and_ancestors(TopAbs_EDGE, TopAbs_WIRE, edg) def wires_from_vertex(self, edg): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_WIRE, edg) def number_of_wires_from_edge(self, edg): return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_WIRE, edg) #=============================================================================== # WIRE <-> FACE #=============================================================================== def wires_from_face(self, face): return self._loop_topo(TopAbs_WIRE, face) def number_of_wires_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_WIRE, face): cnt += 1 return cnt def faces_from_wire(self, wire): return self._map_shapes_and_ancestors(TopAbs_WIRE, TopAbs_FACE, wire) def number_of_faces_from_wires(self, wire): return self._number_shapes_ancestors(TopAbs_WIRE,TopAbs_FACE, wire) #=============================================================================== # VERTEX <-> FACE #=============================================================================== def faces_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def number_of_faces_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def vertices_from_face(self, face): return self._loop_topo(TopAbs_VERTEX, face) def number_of_vertices_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, face): cnt += 1 return cnt #=============================================================================== # FACE <-> SOLID #=============================================================================== def solids_from_face(self, face): return self._map_shapes_and_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def number_of_solids_from_face(self, face): return self._number_shapes_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def faces_from_solids(self, solid): return self._loop_topo(TopAbs_FACE, solid) def number_of_faces_from_solids(self, solid): cnt = 0 for i in self._loop_topo(TopAbs_FACE, solid): cnt += 1 return cnt def dump_topology(shape,level=0): """ Print the details of an object from the top down """ brt = BRep_Tool() s = shape.ShapeType() ts = TopoDS.TopoDS() print print "." * level,topo_lut[shape.ShapeType()], if s == TopAbs_VERTEX: pnt = vertex2pnt(shape_lut[shape]) print "" % (pnt.X(), pnt.Y(), pnt.Z()) it = TopoDS.TopoDS_Iterator(shape) while it.More(): shp = it.Value() it.Next() dump_topology(shp,level + 1 ) def shapeTypeString(shape): st = shape.ShapeType() s = "?" if st == TopAbs_VERTEX: s = "Vertex" if st == TopAbs_SOLID: s = "Solid" if st == TopAbs_EDGE: s = "Edge" if st == TopAbs_FACE: s = "Face" if st == TopAbs_SHELL: s = "Shell" if st == TopAbs_WIRE: s = "Wire" if st == TopAbs_COMPOUND: s = "Compound." if st == TopAbs_COMPSOLID: s = "Compsolid." return s + ":" + str(shape.HashCode(23232232)) \ No newline at end of file From cd38dce96de35958c4776b5bacb29bd9ece55d50 Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 17:35:20 +0200 Subject: [PATCH 13/29] promoted Qt to use an opengl widget --- src/addons/Display/qtDisplay.py | 10 +++++----- src/addons/Utils/Iteration.py | 2 ++ src/addons/Utils/Topology.py | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/addons/Display/qtDisplay.py b/src/addons/Display/qtDisplay.py index f34391ffa..3b38bd4fb 100644 --- a/src/addons/Display/qtDisplay.py +++ b/src/addons/Display/qtDisplay.py @@ -56,11 +56,11 @@ def resizeEvent(self, event): if self._inited: self._display.OnResize() - def initializeGL(self): - import ipdb; ipdb.set_trace() - - def paintGL(self): - import ipdb; ipdb.set_trace() + # def initializeGL(self): + # import ipdb; ipdb.set_trace() + # + # def paintGL(self): + # import ipdb; ipdb.set_trace() def paintEngine(self): return None diff --git a/src/addons/Utils/Iteration.py b/src/addons/Utils/Iteration.py index 5f9c8c02e..bbd5ca510 100644 --- a/src/addons/Utils/Iteration.py +++ b/src/addons/Utils/Iteration.py @@ -5,6 +5,8 @@ from OCC.Utils.Topology import WireExplorer, Topo from OCC.KBE.edge import Edge +# TODO: needs unit testing + class EdgePairsFromWire(object): ''' helper class to loop through a wire and return ordered pairs of edges diff --git a/src/addons/Utils/Topology.py b/src/addons/Utils/Topology.py index c082e622d..8c7dba232 100644 --- a/src/addons/Utils/Topology.py +++ b/src/addons/Utils/Topology.py @@ -1 +1 @@ -# -*- coding: iso-8859-1 -*- #!/usr/bin/env python ##Copyright 2008-2011 Jelle Feringa (jelleferinga@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC 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 3 of the License, or ##(at your option) any later version. ## ##pythonOCC 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 pythonOCC. If not, see . ''' TODO: Hide WireExplorer... BRepTools.Map3DEdges() History: 20-01-2009: initial version 23-03-2009: completed and updated for modular pythonOCC build 23-04-2009: fixed a reference issue ( fixed using ReInit ) ''' from OCC.TopAbs import * from OCC.TopExp import * from OCC.TopoDS import * from OCC.TopTools import * from OCC.BRepTools import * from OCC.BRep import * from OCC.KBE.types_lut import topo_lut, shape_lut from OCC.KBE.edge import Edge from OCC.Utils.Construct import vertex2pnt import sys, itertools __all__ = ['Topo', 'WireExplorer'] class WireExplorer(object): ''' ''' def __init__(self, wire, kbe_types=False): assert isinstance(wire, TopoDS_Wire), 'not a TopoDS_Wire' self.kbe_types = kbe_types self.wire = wire self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _reinitialize(self): self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _loop_topo(self, edges=True): if self.done: self._reinitialize() topologyType = TopoDS_edge if edges else TopoDS_vertex seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.wire_explorer.More(): # loop edges if edges: current_item = self.wire_explorer.Current() # loop vertices else: current_item = self.wire_explorer.CurrentVertex() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.wire_explorer.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = topologyType(occ_iterator.Value()) if self.kbe_types and edges: edge = Edge(topo_to_add) seq.append(edge) else: seq.append(topo_to_add) occ_iterator.Next() return iter(seq) self.done = True def ordered_edges(self): return self._loop_topo(edges=True) def ordered_vertices(self): return self._loop_topo(edges=False) class Topo(object): ''' Topology traversal ''' def __init__(self, myShape, kbe_types=False, ignore_orientation=False): """ implements topology traversal from any TopoDS_Shape this class lets you find how various topological entities are connected from one to another find the faces connected to an edge, find the vertices this edge is made from, get all faces connected to a vertex, and find out how many topological elements are connected from a source *note* when traversing TopoDS_Wire entities, its advised to use the specialized ``WireExplorer`` class, which will return the vertices / edges in the expected order :param myShape: the shape which topology will be traversed :param kbe_types: whether to return OCC.KBE topology types KBE types offers a more consistent and pythonic API, since many useful methods are bound to these objects :param ignore_orientation: filter out TopoDS_* entities of similar TShape but different Orientation for instance, a cube has 24 edges, 4 edges for each of 6 faces that results in 48 vertices, while there are only 8 vertices that have a unique geometric coordinate in certain cases ( computing a graph from the topology ) its preferable to return topological entities that share similar geometry, though differ in orientation by setting the ``ignore_orientation`` variable to True, in case of a cube, just 12 edges and only 8 vertices will be returned for further reference see TopoDS_Shape IsEqual / IsSame methods """ self.myShape = myShape self.kbe_types = kbe_types self.ignore_orientation = ignore_orientation self.topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid } if self.kbe_types: from OCC.KBE.vertex import Vertex from OCC.KBE.edge import Edge from OCC.KBE.face import Face from OCC.KBE.solid import Shell, Solid self.kbeTypes = { TopAbs_VERTEX: Vertex, TopAbs_EDGE: Edge, TopAbs_FACE: Face, TopAbs_SHELL: Shell, TopAbs_SOLID: Solid, } def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=None): ''' this could be a faces generator for a python TopoShape class that way you can just do: for face in srf.faces(): processFace(face) ''' topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid} assert topologyType in self.topoTypes.keys(), '%s not one of %s' %( topologyType, self.topoTypes.keys() ) self.topExp = TopExp_Explorer() # use self.myShape if nothing is specified if topologicalEntity is None and topologyTypeToAvoid is None: self.topExp.Init(self.myShape, topologyType) elif topologicalEntity is None and topologyTypeToAvoid is not None: self.topExp.Init(self.myShape, topologyType, topologyTypeToAvoid) elif topologyTypeToAvoid is None: self.topExp.Init(topologicalEntity, topologyType ) elif topologyTypeToAvoid: self.topExp.Init(topologicalEntity, topologyType, topologyTypeToAvoid) topo_set = set() seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.topExp.More(): current_item = self.topExp.Current() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.topExp.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = self.topoTypes[topologyType](occ_iterator.Value()) # return a KBE type if self.kbe_types: if topologyType in self.kbeTypes: seq.append(self.kbeTypes[topologyType](topo_to_add)) # otherwise a plain TopoDS_Shape subclass else: seq.append(topo_to_add) occ_iterator.Next() if self.ignore_orientation: # filter out those entities that share the same TShape # but do *not* share the same orientation filter_orientation_seq = [] for i in seq: _present = False for j in filter_orientation_seq: if i.IsSame(j): _present = True break if _present is False: filter_orientation_seq.append(i) return filter_orientation_seq else: return iter(seq) def faces(self): ''' loops over all faces ''' return self._loop_topo(TopAbs_FACE) def _number_of_topo(self, iterable): n = 0 for i in iterable: n+=1 return n def number_of_faces(self): return self._number_of_topo(self.faces()) def vertices(self): ''' loops over all vertices ''' return self._loop_topo(TopAbs_VERTEX) def number_of_vertices(self): return self._number_of_topo(self.vertices()) def edges(self): ''' loops over all edges ''' return self._loop_topo(TopAbs_EDGE) def number_of_edges(self): return self._number_of_topo(self.edges()) def wires(self): ''' loops over all wires ''' return self._loop_topo(TopAbs_WIRE) def number_of_wires(self): return self._number_of_topo(self.wires()) def shells(self): ''' loops over all shells ''' return self._loop_topo(TopAbs_SHELL, None) def number_of_shells(self): return self._number_of_topo(self.shells()) def solids(self): ''' loops over all solids ''' return self._loop_topo(TopAbs_SOLID, None) def number_of_solids(self): return self._number_of_topo(self.solids()) def comp_solids(self): ''' loops over all compound solids ''' return self._loop_topo(TopAbs_COMPSOLID) def number_of_comp_solids(self): return self._number_of_topo(self.comp_solids()) def compounds(self): ''' loops over all compounds ''' return self._loop_topo(TopAbs_COMPOUND) def number_of_compounds(self): return self._number_of_topo(self.compounds()) def ordered_vertices_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_vertices() def number_of_ordered_vertices_from_wire(self, wire): return self._number_of_topo(self.ordered_vertices_from_wire(wire)) def ordered_edges_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_edges() def number_of_ordered_edges_from_wire(self, wire): return self._number_of_topo(self.ordered_edges_from_wire(wire)) def _map_shapes_and_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): ''' using the same method @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): yield None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_entity = self.topoTypes[topoTypeB](topology_iterator.Value()) if self.kbe_types: if topoTypeB in self.kbeTypes: topo_entity = self.kbeTypes[topoTypeB](topo_entity) else: raise ValueError('none KBE types called') # return the entity if not in set # to assure we're not returning entities several times if not topo_entity in topo_set: if self.ignore_orientation: unique=True for i in topo_set: if i.IsSame(topo_entity): unique=False break if unique: yield topo_entity else: yield topo_entity topo_set.add(topo_entity) topology_iterator.Next() def _number_shapes_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): '''returns the number of shape ancestors If you want to know how many edges a faces has: _number_shapes_ancestors(self, TopAbs_EDGE, TopAbs_FACE, edg) will return the number of edges a faces has @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): return None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_set.add(topology_iterator.Value()) topology_iterator.Next() return len(topo_set) #=============================================================================== # EDGE <-> FACE #=============================================================================== def faces_from_edge(self, edge): """ :param edge: :return: """ return self._map_shapes_and_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def number_of_faces_from_edge(self, edge): """ :param edge: :return: """ return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def edges_from_face(self, face): """ :param face: :return: """ return self._loop_topo(TopAbs_EDGE, face) def number_of_edges_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, face): cnt += 1 return cnt #=============================================================================== # VERTEX <-> EDGE #=============================================================================== def vertices_from_edge(self, edg): return self._loop_topo(TopAbs_VERTEX, edg) def number_of_vertices_from_edge(self, edg): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, edg): cnt += 1 return cnt def edges_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_EDGE,vertex) def number_of_edges_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_EDGE,vertex) #=============================================================================== # WIRE <-> EDGE #=============================================================================== def edges_from_wire(self, wire): return self._loop_topo(TopAbs_EDGE, wire) def number_of_edges_from_wire(self, wire): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, wire): cnt += 1 return cnt def wires_from_edge(self, edg): return self._map_shapes_and_ancestors(TopAbs_EDGE, TopAbs_WIRE, edg) def wires_from_vertex(self, edg): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_WIRE, edg) def number_of_wires_from_edge(self, edg): return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_WIRE, edg) #=============================================================================== # WIRE <-> FACE #=============================================================================== def wires_from_face(self, face): return self._loop_topo(TopAbs_WIRE, face) def number_of_wires_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_WIRE, face): cnt += 1 return cnt def faces_from_wire(self, wire): return self._map_shapes_and_ancestors(TopAbs_WIRE, TopAbs_FACE, wire) def number_of_faces_from_wires(self, wire): return self._number_shapes_ancestors(TopAbs_WIRE,TopAbs_FACE, wire) #=============================================================================== # VERTEX <-> FACE #=============================================================================== def faces_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def number_of_faces_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def vertices_from_face(self, face): return self._loop_topo(TopAbs_VERTEX, face) def number_of_vertices_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, face): cnt += 1 return cnt #=============================================================================== # FACE <-> SOLID #=============================================================================== def solids_from_face(self, face): return self._map_shapes_and_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def number_of_solids_from_face(self, face): return self._number_shapes_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def faces_from_solids(self, solid): return self._loop_topo(TopAbs_FACE, solid) def number_of_faces_from_solids(self, solid): cnt = 0 for i in self._loop_topo(TopAbs_FACE, solid): cnt += 1 return cnt def dump_topology(shape,level=0): """ Print the details of an object from the top down """ brt = BRep_Tool() s = shape.ShapeType() ts = TopoDS.TopoDS() print print "." * level,topo_lut[shape.ShapeType()], if s == TopAbs_VERTEX: pnt = vertex2pnt(shape_lut[shape]) print "" % (pnt.X(), pnt.Y(), pnt.Z()) it = TopoDS.TopoDS_Iterator(shape) while it.More(): shp = it.Value() it.Next() dump_topology(shp,level + 1 ) def shapeTypeString(shape): st = shape.ShapeType() s = "?" if st == TopAbs_VERTEX: s = "Vertex" if st == TopAbs_SOLID: s = "Solid" if st == TopAbs_EDGE: s = "Edge" if st == TopAbs_FACE: s = "Face" if st == TopAbs_SHELL: s = "Shell" if st == TopAbs_WIRE: s = "Wire" if st == TopAbs_COMPOUND: s = "Compound." if st == TopAbs_COMPSOLID: s = "Compsolid." return s + ":" + str(shape.HashCode(23232232)) \ No newline at end of file +# -*- coding: iso-8859-1 -*- #!/usr/bin/env python ##Copyright 2008-2011 Jelle Feringa (jelleferinga@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC 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 3 of the License, or ##(at your option) any later version. ## ##pythonOCC 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 pythonOCC. If not, see . ''' TODO: Hide WireExplorer... BRepTools.Map3DEdges() History: 20-01-2009: initial version 23-03-2009: completed and updated for modular pythonOCC build 23-04-2009: fixed a reference issue ( fixed using ReInit ) ''' from OCC.TopAbs import * from OCC.TopExp import * from OCC.TopoDS import * from OCC.TopTools import * from OCC.BRepTools import * from OCC.BRep import * from OCC.KBE.types_lut import topo_lut, shape_lut from OCC.KBE.edge import Edge from OCC.Utils.Construct import vertex2pnt import sys, itertools __all__ = ['Topo', 'WireExplorer'] class WireExplorer(object): ''' ''' def __init__(self, wire, kbe_types=False): assert isinstance(wire, TopoDS_Wire), 'not a TopoDS_Wire' self.kbe_types = kbe_types self.wire = wire self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _reinitialize(self): self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _loop_topo(self, edges=True): if self.done: self._reinitialize() topologyType = TopoDS_edge if edges else TopoDS_vertex seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.wire_explorer.More(): # loop edges if edges: current_item = self.wire_explorer.Current() # loop vertices else: current_item = self.wire_explorer.CurrentVertex() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.wire_explorer.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = topologyType(occ_iterator.Value()) if self.kbe_types and edges: edge = Edge(topo_to_add) seq.append(edge) else: seq.append(topo_to_add) occ_iterator.Next() self.done = True return iter(seq) def ordered_edges(self): return self._loop_topo(edges=True) def ordered_vertices(self): return self._loop_topo(edges=False) class Topo(object): ''' Topology traversal ''' def __init__(self, myShape, kbe_types=False, ignore_orientation=False): """ implements topology traversal from any TopoDS_Shape this class lets you find how various topological entities are connected from one to another find the faces connected to an edge, find the vertices this edge is made from, get all faces connected to a vertex, and find out how many topological elements are connected from a source *note* when traversing TopoDS_Wire entities, its advised to use the specialized ``WireExplorer`` class, which will return the vertices / edges in the expected order :param myShape: the shape which topology will be traversed :param kbe_types: whether to return OCC.KBE topology types KBE types offers a more consistent and pythonic API, since many useful methods are bound to these objects :param ignore_orientation: filter out TopoDS_* entities of similar TShape but different Orientation for instance, a cube has 24 edges, 4 edges for each of 6 faces that results in 48 vertices, while there are only 8 vertices that have a unique geometric coordinate in certain cases ( computing a graph from the topology ) its preferable to return topological entities that share similar geometry, though differ in orientation by setting the ``ignore_orientation`` variable to True, in case of a cube, just 12 edges and only 8 vertices will be returned for further reference see TopoDS_Shape IsEqual / IsSame methods """ self.myShape = myShape self.kbe_types = kbe_types self.ignore_orientation = ignore_orientation self.topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid } if self.kbe_types: from OCC.KBE.vertex import Vertex from OCC.KBE.edge import Edge from OCC.KBE.face import Face from OCC.KBE.solid import Shell, Solid self.kbeTypes = { TopAbs_VERTEX: Vertex, TopAbs_EDGE: Edge, TopAbs_FACE: Face, TopAbs_SHELL: Shell, TopAbs_SOLID: Solid, } def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=None): ''' this could be a faces generator for a python TopoShape class that way you can just do: for face in srf.faces(): processFace(face) ''' topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid} assert topologyType in self.topoTypes.keys(), '%s not one of %s' %( topologyType, self.topoTypes.keys() ) self.topExp = TopExp_Explorer() # use self.myShape if nothing is specified if topologicalEntity is None and topologyTypeToAvoid is None: self.topExp.Init(self.myShape, topologyType) elif topologicalEntity is None and topologyTypeToAvoid is not None: self.topExp.Init(self.myShape, topologyType, topologyTypeToAvoid) elif topologyTypeToAvoid is None: self.topExp.Init(topologicalEntity, topologyType ) elif topologyTypeToAvoid: self.topExp.Init(topologicalEntity, topologyType, topologyTypeToAvoid) topo_set = set() seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.topExp.More(): current_item = self.topExp.Current() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.topExp.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = self.topoTypes[topologyType](occ_iterator.Value()) # return a KBE type if self.kbe_types: if topologyType in self.kbeTypes: seq.append(self.kbeTypes[topologyType](topo_to_add)) # otherwise a plain TopoDS_Shape subclass else: seq.append(topo_to_add) occ_iterator.Next() if self.ignore_orientation: # filter out those entities that share the same TShape # but do *not* share the same orientation filter_orientation_seq = [] for i in seq: _present = False for j in filter_orientation_seq: if i.IsSame(j): _present = True break if _present is False: filter_orientation_seq.append(i) return filter_orientation_seq else: return iter(seq) def faces(self): ''' loops over all faces ''' return self._loop_topo(TopAbs_FACE) def _number_of_topo(self, iterable): n = 0 for i in iterable: n+=1 return n def number_of_faces(self): return self._number_of_topo(self.faces()) def vertices(self): ''' loops over all vertices ''' return self._loop_topo(TopAbs_VERTEX) def number_of_vertices(self): return self._number_of_topo(self.vertices()) def edges(self): ''' loops over all edges ''' return self._loop_topo(TopAbs_EDGE) def number_of_edges(self): return self._number_of_topo(self.edges()) def wires(self): ''' loops over all wires ''' return self._loop_topo(TopAbs_WIRE) def number_of_wires(self): return self._number_of_topo(self.wires()) def shells(self): ''' loops over all shells ''' return self._loop_topo(TopAbs_SHELL, None) def number_of_shells(self): return self._number_of_topo(self.shells()) def solids(self): ''' loops over all solids ''' return self._loop_topo(TopAbs_SOLID, None) def number_of_solids(self): return self._number_of_topo(self.solids()) def comp_solids(self): ''' loops over all compound solids ''' return self._loop_topo(TopAbs_COMPSOLID) def number_of_comp_solids(self): return self._number_of_topo(self.comp_solids()) def compounds(self): ''' loops over all compounds ''' return self._loop_topo(TopAbs_COMPOUND) def number_of_compounds(self): return self._number_of_topo(self.compounds()) def ordered_vertices_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_vertices() def number_of_ordered_vertices_from_wire(self, wire): return self._number_of_topo(self.ordered_vertices_from_wire(wire)) def ordered_edges_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_edges() def number_of_ordered_edges_from_wire(self, wire): return self._number_of_topo(self.ordered_edges_from_wire(wire)) def _map_shapes_and_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): ''' using the same method @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): yield None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_entity = self.topoTypes[topoTypeB](topology_iterator.Value()) if self.kbe_types: if topoTypeB in self.kbeTypes: topo_entity = self.kbeTypes[topoTypeB](topo_entity) else: raise ValueError('none KBE types called') # return the entity if not in set # to assure we're not returning entities several times if not topo_entity in topo_set: if self.ignore_orientation: unique=True for i in topo_set: if i.IsSame(topo_entity): unique=False break if unique: yield topo_entity else: yield topo_entity topo_set.add(topo_entity) topology_iterator.Next() def _number_shapes_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): '''returns the number of shape ancestors If you want to know how many edges a faces has: _number_shapes_ancestors(self, TopAbs_EDGE, TopAbs_FACE, edg) will return the number of edges a faces has @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): return None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_set.add(topology_iterator.Value()) topology_iterator.Next() return len(topo_set) #=============================================================================== # EDGE <-> FACE #=============================================================================== def faces_from_edge(self, edge): """ :param edge: :return: """ return self._map_shapes_and_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def number_of_faces_from_edge(self, edge): """ :param edge: :return: """ return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def edges_from_face(self, face): """ :param face: :return: """ return self._loop_topo(TopAbs_EDGE, face) def number_of_edges_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, face): cnt += 1 return cnt #=============================================================================== # VERTEX <-> EDGE #=============================================================================== def vertices_from_edge(self, edg): return self._loop_topo(TopAbs_VERTEX, edg) def number_of_vertices_from_edge(self, edg): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, edg): cnt += 1 return cnt def edges_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_EDGE,vertex) def number_of_edges_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_EDGE,vertex) #=============================================================================== # WIRE <-> EDGE #=============================================================================== def edges_from_wire(self, wire): return self._loop_topo(TopAbs_EDGE, wire) def number_of_edges_from_wire(self, wire): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, wire): cnt += 1 return cnt def wires_from_edge(self, edg): return self._map_shapes_and_ancestors(TopAbs_EDGE, TopAbs_WIRE, edg) def wires_from_vertex(self, edg): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_WIRE, edg) def number_of_wires_from_edge(self, edg): return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_WIRE, edg) #=============================================================================== # WIRE <-> FACE #=============================================================================== def wires_from_face(self, face): return self._loop_topo(TopAbs_WIRE, face) def number_of_wires_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_WIRE, face): cnt += 1 return cnt def faces_from_wire(self, wire): return self._map_shapes_and_ancestors(TopAbs_WIRE, TopAbs_FACE, wire) def number_of_faces_from_wires(self, wire): return self._number_shapes_ancestors(TopAbs_WIRE,TopAbs_FACE, wire) #=============================================================================== # VERTEX <-> FACE #=============================================================================== def faces_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def number_of_faces_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def vertices_from_face(self, face): return self._loop_topo(TopAbs_VERTEX, face) def number_of_vertices_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, face): cnt += 1 return cnt #=============================================================================== # FACE <-> SOLID #=============================================================================== def solids_from_face(self, face): return self._map_shapes_and_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def number_of_solids_from_face(self, face): return self._number_shapes_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def faces_from_solids(self, solid): return self._loop_topo(TopAbs_FACE, solid) def number_of_faces_from_solids(self, solid): cnt = 0 for i in self._loop_topo(TopAbs_FACE, solid): cnt += 1 return cnt def dump_topology(shape,level=0): """ Print the details of an object from the top down """ brt = BRep_Tool() s = shape.ShapeType() ts = TopoDS.TopoDS() print print "." * level,topo_lut[shape.ShapeType()], if s == TopAbs_VERTEX: pnt = vertex2pnt(shape_lut[shape]) print "" % (pnt.X(), pnt.Y(), pnt.Z()) it = TopoDS.TopoDS_Iterator(shape) while it.More(): shp = it.Value() it.Next() dump_topology(shp,level + 1 ) def shapeTypeString(shape): st = shape.ShapeType() s = "?" if st == TopAbs_VERTEX: s = "Vertex" if st == TopAbs_SOLID: s = "Solid" if st == TopAbs_EDGE: s = "Edge" if st == TopAbs_FACE: s = "Face" if st == TopAbs_SHELL: s = "Shell" if st == TopAbs_WIRE: s = "Wire" if st == TopAbs_COMPOUND: s = "Compound." if st == TopAbs_COMPSOLID: s = "Compsolid." return s + ":" + str(shape.HashCode(23232232)) \ No newline at end of file From d674590b9f2b9be52352a576031adfb423f12d37 Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 18:34:14 +0200 Subject: [PATCH 14/29] more smaller fixes, while testing and checking all examples --- src/addons/DYN/Context.py | 2 -- src/addons/DataExchange/utils.py | 2 +- src/addons/Display/SimpleGui.py | 5 ++-- src/examples/DYN/dyn_demo.py | 11 +++----- src/examples/DYN/trimesh_collision.py | 28 ++++++++++++------- src/examples/FairCurve/faircurve.py | 2 -- src/examples/GEOM/partition.py | 2 +- .../test_garbage_collector.py | 2 +- .../GenerateScreenshot/export_to_image.py | 3 +- src/examples/Geometry/airfoil.py | 7 +++-- src/examples/Geometry/geomplate.py | 8 +++--- .../InteractiveFeatureTree/occ_display.py | 7 ++--- .../InteractiveFeatureTree/occ_model.py | 4 +-- src/examples/InteractiveFeatureTree/utils.py | 4 +-- 14 files changed, 43 insertions(+), 44 deletions(-) diff --git a/src/addons/DYN/Context.py b/src/addons/DYN/Context.py index eb058f98a..398d1b30d 100644 --- a/src/addons/DYN/Context.py +++ b/src/addons/DYN/Context.py @@ -220,7 +220,6 @@ def start_open_loop(self, quick=False): xg=shape.x_g# yg=shape.y_g# COG coordinated in the local referential zg=shape.z_g# - print 'xg,yg,zg',xg,yg,zg u=x-(xg*a11+yg*a12+zg*a13) v=y-(xg*a21+yg*a22+zg*a23)#COG coordinate in the global referential w=z-(xg*a31+yg*a32+zg*a33) @@ -245,7 +244,6 @@ def start_open_loop(self, quick=False): self._perform_callbacks() # Then increment time and loop simulation t += self._delta_t - print 't',t # increment the step index current_time_step_index += 1 diff --git a/src/addons/DataExchange/utils.py b/src/addons/DataExchange/utils.py index c635e86da..b5e4e7551 100644 --- a/src/addons/DataExchange/utils.py +++ b/src/addons/DataExchange/utils.py @@ -46,7 +46,7 @@ def shape_to_file(shape, pth, filename, format='iges'): def file_to_shape(pth): '''get a Shape from an .iges or .step file''' - assert os.path.isfile(pth), '%s is not a valid directory' % (pth) + assert os.path.isfile(pth), '%s is not a valid file' % (pth) ext = os.path.splitext(pth)[1] print 'ext', ext assert ext in ['.iges', '.igs', '.stp', '.step', '.brep', '.stl'], '%s is not an readable format' % ( ext ) diff --git a/src/addons/Display/SimpleGui.py b/src/addons/Display/SimpleGui.py index 99fe31918..b0453b6ad 100644 --- a/src/addons/Display/SimpleGui.py +++ b/src/addons/Display/SimpleGui.py @@ -75,7 +75,8 @@ def get_bg_abs_filename(): else: return bg_abs_filename -def safe_yield(USED_BACKEND): +def safe_yield(): + global USED_BACKEND if USED_BACKEND == 'wx': import wx wx.SafeYield() @@ -89,7 +90,7 @@ def safe_yield(USED_BACKEND): QtGui.QApplication.processEvents() def init_display(): - global display, add_menu, add_function_to_menu, start_display, app, win + global display, add_menu, add_function_to_menu, start_display, app, win, USED_BACKEND USED_BACKEND = get_backend() diff --git a/src/examples/DYN/dyn_demo.py b/src/examples/DYN/dyn_demo.py index 07cc7257b..81f323d3f 100644 --- a/src/examples/DYN/dyn_demo.py +++ b/src/examples/DYN/dyn_demo.py @@ -30,7 +30,7 @@ import ode from OCC.Display.SimpleGui import * -from OCC.Utils.Construct import translate_topods_from_vector, make_plane +from OCC.Utils.Construct import translate_topods_from_vector, make_plane, make_face display, start_display, add_menu, add_function_to_menu = init_display() def rotating_box(event=None): @@ -183,11 +183,10 @@ def floor(): PL = gp_Pln(P1,gp_Dir(V1)) aPlane = GC_MakePlane(PL).Value() aSurface = Geom_RectangularTrimmedSurface( aPlane, -100., 100., -60., 60., 1, 1 ) - face = BRepBuilderAPI_MakeFace(aSurface.GetHandle()) - face.Build() + face = make_face(aSurface.GetHandle(), 1e-6) floor = ode.GeomPlane(dyn_context._space, (0,0,1), -100) references.append(floor) - display.DisplayColoredShape(face.Shape(),'RED') + display.DisplayColoredShape(face,'RED') display.FitAll() floor() @@ -343,7 +342,7 @@ def hinge(event=None): prev_center = center # get the 1st block, the one one the ground... - xmin, ymin, zmin, xmax, ymax, zmax = get_boundingbox(cube).Get() + xmin, ymin, zmin, xmax, ymax, zmax = get_boundingbox(cube) # set the lower block in motion vec1 = (12, 88, 0) first.setLinearVel(vec1) @@ -361,8 +360,6 @@ def hinge(event=None): # create a floor... floor = ode.GeomPlane(dyn_context._space, (0,0,1), zmin) def f(): - print 'first:',first.getPosition() - print 'velo:', first.getLinearVel() XXX = 0.15 * N first.setLinearVel((0, XXX,0)) dyn_shape.setLinearVel((0,-XXX,0)) diff --git a/src/examples/DYN/trimesh_collision.py b/src/examples/DYN/trimesh_collision.py index 5c8d602e1..f343d4497 100644 --- a/src/examples/DYN/trimesh_collision.py +++ b/src/examples/DYN/trimesh_collision.py @@ -17,19 +17,17 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . +import ode + from OCC.BRepPrimAPI import * -from OCC.GC import * -from OCC.Geom import * from OCC.gp import * -from OCC.BRepBuilderAPI import * from OCC.Utils.Construct import translate_topods_from_vector, make_plane -from OCC.DYN.Context import DynamicSimulationContext, DynamicShape +from OCC.DYN.Context import DynamicSimulationContext from OCC.TopoDS import * from OCC.BRep import * from OCC.BRepTools import * -import ode - from OCC.Display.SimpleGui import * + display, start_display, add_menu, add_function_to_menu = init_display() @@ -88,7 +86,12 @@ def falling_torus_torus(event=None): dyn_context.set_simulation_duration(20) #1s forthe simulation dyn_context.set_time_step(0.01) dyn_context.start_open_loop() - + + +from OCC.DataExchange.utils import file_to_shape + + + def falling_pump(event=None): def load_brep(filename): # Load the shape from a file @@ -96,15 +99,20 @@ def load_brep(filename): builder = BRep_Builder() BRepTools_Read(aShape,str(filename),builder) return aShape - + # Just a copy/paste of the torus code display.EraseAll() dyn_context = DynamicSimulationContext() dyn_context.set_display(display, safe_yield) dyn_context.enable_collision_detection() dyn_context.enable_gravity() - - s1 = load_brep('../../data/BREP/40_pump_body.brep') + + _pth = os.path.abspath( + os.path.join( os.path.split(os.path.abspath(__file__))[0], + '../data/brep/Pump_Bottom.brep') + ) + s1 = file_to_shape(_pth) + d = dyn_context.register_shape(s1,enable_collision_detection=True,use_trimesh=True) # The plane (note: this plane is not a dynamic shape, it's just displayed) diff --git a/src/examples/FairCurve/faircurve.py b/src/examples/FairCurve/faircurve.py index e2ddbab84..4c5a1fdcd 100644 --- a/src/examples/FairCurve/faircurve.py +++ b/src/examples/FairCurve/faircurve.py @@ -18,11 +18,9 @@ ##along with pythonOCC. If not, see . from OCC.gp import * -from OCC.Geom2d import * from OCC.Geom import * from OCC.FairCurve import * -from OCC.Utils.Construct import * from OCC.Display.SimpleGui import * display, start_display, add_menu, add_function_to_menu = init_display() from OCC.Utils.Construct import make_edge diff --git a/src/examples/GEOM/partition.py b/src/examples/GEOM/partition.py index 7e7e2a7a1..76e939721 100644 --- a/src/examples/GEOM/partition.py +++ b/src/examples/GEOM/partition.py @@ -13,7 +13,7 @@ liY = make_line(gp_Pnt(0,-10,0), gp_Pnt(0,10,0)) liZ = make_line(gp_Pnt(0,0,-10), gp_Pnt(0,0,10)) -box = make_cube(gp_Pnt(-20,-20,-20), gp_Pnt(20,20,20)) +box = make_box(gp_Pnt(-20,-20,-20), gp_Pnt(20,20,20)) pl1 = make_closed_polygon(gp_Pnt(-10,-10,0), gp_Pnt(10,-10,0), diff --git a/src/examples/GarbageCollector/test_garbage_collector.py b/src/examples/GarbageCollector/test_garbage_collector.py index 0b91c7915..8bbdebef0 100644 --- a/src/examples/GarbageCollector/test_garbage_collector.py +++ b/src/examples/GarbageCollector/test_garbage_collector.py @@ -3,7 +3,7 @@ from OCC.BRepPrimAPI import * from OCC.TopExp import * from OCC.TopAbs import TopAbs_FACE -from OCC.TopoDS import * + def mem(size="rss"): """Generalization; memory sizes: rss, rsz, vsz.""" diff --git a/src/examples/GenerateScreenshot/export_to_image.py b/src/examples/GenerateScreenshot/export_to_image.py index b2b164855..dae6c5f1d 100644 --- a/src/examples/GenerateScreenshot/export_to_image.py +++ b/src/examples/GenerateScreenshot/export_to_image.py @@ -16,8 +16,7 @@ ##along with pythonOCC. If not, see . from OCC.Display.SimpleGui import * -from OCC.TopAbs import * -from OCC.BRepPrimAPI import * +from OCC.BRepPrimAPI import BRepPrimAPI_MakeBox display, start_display, add_menu, add_function_to_menu = init_display() my_box = BRepPrimAPI_MakeBox(10.,20.,30.).Shape() diff --git a/src/examples/Geometry/airfoil.py b/src/examples/Geometry/airfoil.py index f11da7d2d..49234c09f 100644 --- a/src/examples/Geometry/airfoil.py +++ b/src/examples/Geometry/airfoil.py @@ -21,7 +21,7 @@ # Explanations for this script can be found at # http://pythonocc.wordpress.com/2013/04/01/using-external-airfoil-data-to-create-a-solid-wing/ # -import re, urllib2 +import urllib2 from OCC.BRepBuilderAPI import BRepBuilderAPI_MakeFace from OCC.BRepPrimAPI import BRepPrimAPI_MakePrism @@ -29,8 +29,9 @@ from OCC.GeomAPI import GeomAPI_To3d from OCC.gp import gp_Pnt, gp_Vec, gp_Pnt2d, gp_Pln, gp_Dir from OCC.TColgp import TColgp_Array1OfPnt2d -from OCC.Utils.Construct import make_wire, make_edge, make_vertex - +from OCC.Utils.Construct import make_wire, make_edge + + class UiucAirfoil: """ Airfoil with a section from the UIUC database diff --git a/src/examples/Geometry/geomplate.py b/src/examples/Geometry/geomplate.py index 95a21972d..ddae6d2bd 100644 --- a/src/examples/Geometry/geomplate.py +++ b/src/examples/Geometry/geomplate.py @@ -35,10 +35,9 @@ import types, sys, time from OCC.Display.SimpleGui import init_display -from OCC.Utils.DataExchange.IGES import IGESImporter +from OCC.DataExchange.IGES import IGESImporter from OCC.BRepFill import * from OCC.GeomPlate import * -from OCC.GEOMAlgo import * display, start_display, add_menu, add_function_to_menu = init_display() @@ -94,7 +93,7 @@ def build_plate(polygon, points): uMin, uMax, vMin, vMax = srf.GetObject().Bounds() - return make_face(plate.Surface(), uMin, uMax, vMin, vMax) + return make_face(plate.Surface(), uMin, uMax, vMin, vMax, 1e-4) def radius_at_uv(face, u, v): ''' @@ -214,7 +213,7 @@ def build_curve_network(event=None): ''' print 'Importing IGES file...', pth = os.path.dirname(os.path.abspath(__file__)) - pth = os.path.abspath(os.path.join(pth, '../../data/IGES/curve_geom_plate.igs')) + pth = os.path.abspath(os.path.join(pth, '../data/IGES/curve_geom_plate.igs')) iges = IGESImporter(pth) iges.read_file() print 'done.' @@ -226,6 +225,7 @@ def build_curve_network(event=None): print 'done.' display.EraseAll() display.DisplayShape(edges_list) + display.DisplayShape(face) display.FitAll() print 'Cutting out of edges...', # Make a wire from outer edges diff --git a/src/examples/InteractiveFeatureTree/occ_display.py b/src/examples/InteractiveFeatureTree/occ_display.py index c73d8b13e..fceb9e0de 100644 --- a/src/examples/InteractiveFeatureTree/occ_display.py +++ b/src/examples/InteractiveFeatureTree/occ_display.py @@ -18,10 +18,10 @@ ##along with pythonOCC. If not, see . -from enthought.traits.api import HasTraits, Instance, Event, \ +from traits.api import HasTraits, Instance, Event, \ List, Str, Button, Enum -from enthought.traits.ui.api import CustomEditor, View, Item, TreeEditor, TreeNode,\ +from traitsui.api import CustomEditor, View, Item, TreeEditor, TreeNode,\ VSplit, HSplit from OCC.Display.wxDisplay import wxViewer3d @@ -34,9 +34,6 @@ import os -CSF_GraphicShr = r"/usr/local/lib/libTKOpenGl.so" #OK for linux -if os.path.exists(CSF_GraphicShr) and os.environ['CSF_GraphicShr'] != '': #slightly safer - os.environ['CSF_GraphicShr'] = CSF_GraphicShr class MyCanvas(wxViewer3d): diff --git a/src/examples/InteractiveFeatureTree/occ_model.py b/src/examples/InteractiveFeatureTree/occ_model.py index 3ca75cb58..ee152779d 100644 --- a/src/examples/InteractiveFeatureTree/occ_model.py +++ b/src/examples/InteractiveFeatureTree/occ_model.py @@ -18,11 +18,11 @@ ##along with pythonOCC. If not, see . -from enthought.traits.api import (HasTraits, Property, Bool, +from traits.api import (HasTraits, Property, Bool, on_trait_change, cached_property, Instance, List, Str, Enum) -from enthought.traits.ui.api import View, Item +from traitsui.api import View, Item from utils import Tuple, EditorTraits, Int, Float, Range diff --git a/src/examples/InteractiveFeatureTree/utils.py b/src/examples/InteractiveFeatureTree/utils.py index 5e3f60713..4cd2e0e82 100644 --- a/src/examples/InteractiveFeatureTree/utils.py +++ b/src/examples/InteractiveFeatureTree/utils.py @@ -18,11 +18,11 @@ ##along with pythonOCC. If not, see . -from enthought.traits.api import (Range as _Range, +from traits.api import (Range as _Range, Tuple as _Tuple, Int as _Int, Float as _Float) -from enthought.traits.ui.api import TupleEditor +from traitsui.api import TupleEditor class EditorTraits(object): """ From 08f822c3efaa28bac1133a5c540b3e352c0b95cb Mon Sep 17 00:00:00 2001 From: jf--- Date: Wed, 24 Apr 2013 19:28:19 +0200 Subject: [PATCH 15/29] small additions to DYN --- src/addons/DYN/Joints.py | 68 +++++++--------- src/examples/DYN/dyn_demo.py | 80 +++++++++++++++++++ .../InteractiveFeatureTree/framework.py | 3 +- .../InteractiveFeatureTree/occ_model.py | 5 +- 4 files changed, 116 insertions(+), 40 deletions(-) diff --git a/src/addons/DYN/Joints.py b/src/addons/DYN/Joints.py index 37854f245..3351dbb63 100644 --- a/src/addons/DYN/Joints.py +++ b/src/addons/DYN/Joints.py @@ -22,56 +22,50 @@ from OCC.gp import * -#class BaseJoint(ode.Joint): -# ''' Base class for all joints -# ''' -# def __init__(self,*kargs): -# ode.Join.__ini__(self,*kargs) -# print 'BaseJoint initialized' -# #ode.Joint.__init__(self,*kargs) -# # self._parent_context = kargs[0] -# -# def attach_shapes(self,shape1,shape2): -# dynamic_context1 = shape1.get_dynamic_context() -# dynamic_context2 = shape2.get_dynamic_context() -# assert(dynamic_context1 == dynamic_context2) -# self.attach(shape1,shape2) - -class DynamicHingeJoint(ode.HingeJoint): - """ Create a hinge joint between 2 dynamic shapes - """ - def _init__(self,dyn_context): - self.dyn_context = dyn_context - ode.HingeJoint.__init__(self) - +class BaseJoint(object): + ''' Base class for all joints + ''' def set_anchor(self,gp_point_center): ''' Set the anchor of the ball joint ''' self.setAnchor(gp_point_center.Coord()) - + + def attach_shapes(self,shape1,shape2): + self.attach(shape1,shape2) + def set_axis(self, gp_direction): ''' sets the hinge axis, which is a gp_Dir ''' self.setAxis(gp_direction.Coord()) - - def attach_shapes(self,shape1,shape2): - self.attach(shape1,shape2) - -class DynamicBallJoint(ode.BallJoint): + +class DynamicHingeJoint(ode.HingeJoint, BaseJoint): + """ Create a hinge joint between 2 dynamic shapes + """ + def __init__(self,dyn_context): + self.dyn_context = dyn_context + ode.HingeJoint.__init__(self,dyn_context) + +class DynamicUniversalJoint(ode.HingeJoint, BaseJoint): + """ Create a hinge joint between 2 dynamic shapes + """ + def __init__(self,dyn_context): + self.dyn_context = dyn_context + ode.UniversalJoint.__init__(self,dyn_context) + +class DynamicSliderJoint(ode.SliderJoint, BaseJoint): + """ Create a slider joint between 2 dynamic shapes + """ + def __init__(self,dyn_context): + self.dyn_context = dyn_context + ode.SliderJoint.__init__(self, dyn_context) + #del self.set_anchor # not present with a slider joint + +class DynamicBallJoint(ode.BallJoint, BaseJoint): """ Create a joint between 2 DynamicShapes """ def __init__(self,dyn_context): self.dyn_context = dyn_context ode.BallJoint.__init__(self,dyn_context) - - def set_anchor(self,gp_point_center): - ''' Set the anchor of the ball joint - ''' - coords = gp_point_center.Coord() - self.setAnchor(coords) - - def attach_shapes(self, shape1, shape2): - self.attach(shape1,shape2) import os diff --git a/src/examples/DYN/dyn_demo.py b/src/examples/DYN/dyn_demo.py index 81f323d3f..a4e1ed53e 100644 --- a/src/examples/DYN/dyn_demo.py +++ b/src/examples/DYN/dyn_demo.py @@ -31,6 +31,8 @@ from OCC.Display.SimpleGui import * from OCC.Utils.Construct import translate_topods_from_vector, make_plane, make_face +from OCC.DYN.Joints import DynamicSliderJoint + display, start_display, add_menu, add_function_to_menu = init_display() def rotating_box(event=None): @@ -373,6 +375,82 @@ def f(): dyn_context.register_post_step_callback(f) dyn_context.start_open_loop(True) +def adhesion(event=None): + ''' + hinge joint example adapted from pyode + http://pyode.sourceforge.net/tutorials/tutorial2.html + + ''' + from OCC.Utils.Common import center_boundingbox + + display.EraseAll() + # Create the dynamic context + dyn_context = DynamicSimulationContext() + dyn_context.set_display(display, safe_yield) + dyn_context.enable_collision_detection() + dyn_context.enable_gravity() + # create the table + block1 = BRepPrimAPI_MakeBox(4,1,1).Shape() + + N = 12 + + dyn_shapes = [] + for i in range(1,N): + table_shape = translate_topods_from_vector(block1, gp_Vec(0,0,2*(i*0.5)), copy=True) + dyn_shape = dyn_context.register_shape(table_shape, enable_collision_detection=True, use_boundingbox=True) + dyn_shapes.append((dyn_shape,table_shape)) + + _dyn_shapes = iter(dyn_shapes) + prev, table_shape = _dyn_shapes.next() + # safe for future reference + first, cube = prev, table_shape + prev_center = center_boundingbox(table_shape) + + slider_vec = gp_Dir(1,1,0) + + for i,xxx in enumerate(_dyn_shapes): + dyn_shape, table_shape = xxx + bj = DynamicSliderJoint(dyn_context) + bj.set_axis(slider_vec) + center = center_boundingbox(table_shape) + if i == 0: + bj.attach_shapes(prev, ode.environment) + first_joint = bj + else: + bj.attach_shapes(prev, dyn_shape) + dyn_context.register_joint(bj) + prev=dyn_shape + prev_center = center + + # get the 1st block, the one one the ground... + xmin, ymin, zmin, xmax, ymax, zmax = get_boundingbox(cube) + # set the middle block in motion + vec1 = (160, 66, 0) + #vec1 = (1.20, 0.66, 0) + middle, topods = dyn_shapes[N/2] + + middle.setLinearVel(vec1) + #middle.setForce(vec1) + + # change the color of the bottom element a little... + ais = middle.get_ais_shape().GetObject() + from OCC.Graphic3d import Graphic3d_NOM_SILVER + ais.SetMaterial(Graphic3d_NOM_SILVER) + + bj.attach_shapes( dyn_shape, ode.environment ) + first_joint.attach_shapes( first, ode.environment ) + + floor = ode.GeomPlane(dyn_context._space, (0,0,1), zmin) + + dyn_context.mu = 0 # icey!!! + dyn_context.setERP(0.1) # 0.2 default + dyn_context.setCFM(1e-12) # 1e-10 default + dyn_context.set_simulation_duration(1200) + dyn_context.set_animation_frame_rate(40) + dyn_context.set_time_step(0.01) + dyn_context.start_open_loop(True) + + def exit(event=None): sys.exit() @@ -385,4 +463,6 @@ def exit(event=None): add_function_to_menu('rigid body simulation sample', dominos) add_function_to_menu('rigid body simulation sample', collisions) add_function_to_menu('rigid body simulation sample', hinge) + add_function_to_menu('rigid body simulation sample', adhesion) + adhesion() start_display() diff --git a/src/examples/InteractiveFeatureTree/framework.py b/src/examples/InteractiveFeatureTree/framework.py index a5a715c7d..123778adf 100644 --- a/src/examples/InteractiveFeatureTree/framework.py +++ b/src/examples/InteractiveFeatureTree/framework.py @@ -42,4 +42,5 @@ # # We'll add all shapes under this node in the label tree # -shape_root = ts.NewChild(root) +# shape_root = ts.NewChild(root) +shape_root = root.NewChild() diff --git a/src/examples/InteractiveFeatureTree/occ_model.py b/src/examples/InteractiveFeatureTree/occ_model.py index ee152779d..c4eeb19d6 100644 --- a/src/examples/InteractiveFeatureTree/occ_model.py +++ b/src/examples/InteractiveFeatureTree/occ_model.py @@ -90,8 +90,9 @@ def on_input_change(self, obj, name, vold, vnew): self._inputs.append(vnew) def _parent_label_changed(self, old_label, new_label): - ts = TDF.TDF_TagSource() - self.label = ts.NewChild(new_label) + # ts = TDF.TDF_TagSource() + # self.label = ts.NewChild(new_label) + self.label = self.parent_label.NewChild() def on_modify(self, vnew): if vnew: From 4b3f4bd847cc158702aa34761f3ab974111aaf16 Mon Sep 17 00:00:00 2001 From: jf--- Date: Thu, 25 Apr 2013 10:15:15 +0200 Subject: [PATCH 16/29] interactive feauture tree should make the distinction between qt and wx --- src/examples/InteractiveFeatureTree/qt/__init__.py | 1 + src/examples/InteractiveFeatureTree/qt/canvas.py | 1 + src/examples/InteractiveFeatureTree/wx/__init__.py | 1 + src/examples/InteractiveFeatureTree/wx/canvas.py | 1 + 4 files changed, 4 insertions(+) create mode 100644 src/examples/InteractiveFeatureTree/qt/__init__.py create mode 100644 src/examples/InteractiveFeatureTree/qt/canvas.py create mode 100644 src/examples/InteractiveFeatureTree/wx/__init__.py create mode 100644 src/examples/InteractiveFeatureTree/wx/canvas.py diff --git a/src/examples/InteractiveFeatureTree/qt/__init__.py b/src/examples/InteractiveFeatureTree/qt/__init__.py new file mode 100644 index 000000000..ad7a9f511 --- /dev/null +++ b/src/examples/InteractiveFeatureTree/qt/__init__.py @@ -0,0 +1 @@ +__author__ = 'jelleferinga' diff --git a/src/examples/InteractiveFeatureTree/qt/canvas.py b/src/examples/InteractiveFeatureTree/qt/canvas.py new file mode 100644 index 000000000..ad7a9f511 --- /dev/null +++ b/src/examples/InteractiveFeatureTree/qt/canvas.py @@ -0,0 +1 @@ +__author__ = 'jelleferinga' diff --git a/src/examples/InteractiveFeatureTree/wx/__init__.py b/src/examples/InteractiveFeatureTree/wx/__init__.py new file mode 100644 index 000000000..ad7a9f511 --- /dev/null +++ b/src/examples/InteractiveFeatureTree/wx/__init__.py @@ -0,0 +1 @@ +__author__ = 'jelleferinga' diff --git a/src/examples/InteractiveFeatureTree/wx/canvas.py b/src/examples/InteractiveFeatureTree/wx/canvas.py new file mode 100644 index 000000000..ad7a9f511 --- /dev/null +++ b/src/examples/InteractiveFeatureTree/wx/canvas.py @@ -0,0 +1 @@ +__author__ = 'jelleferinga' From e81534ccc34718f29cab03a907aa6f53ca3e6789 Mon Sep 17 00:00:00 2001 From: jf--- Date: Thu, 25 Apr 2013 11:10:19 +0200 Subject: [PATCH 17/29] deleting display examples that are no longer supported --- src/addons/Display/XDisplay.py | 186 --------------------------- src/addons/Display/wxSamplesGui2d.py | 88 ------------- 2 files changed, 274 deletions(-) delete mode 100644 src/addons/Display/XDisplay.py delete mode 100644 src/addons/Display/wxSamplesGui2d.py diff --git a/src/addons/Display/XDisplay.py b/src/addons/Display/XDisplay.py deleted file mode 100644 index 5358ea505..000000000 --- a/src/addons/Display/XDisplay.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python - -##Copyright 2008-2011 Thomas Paviot (tpaviot@gmail.com) -## -##This file is part of pythonOCC. -## -##pythonOCC 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 3 of the License, or -##(at your option) any later version. -## -##pythonOCC 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 pythonOCC. If not, see . - -import os -import sys -import thread -try: - from Xlib import display, X, XK -except: - print "python-xlib must be installed. Check http://sf.net/projects/python-xlib" - sys.exit(0) -import OCCViewer - -class XOCCWindow: - def __init__(self, display,title='pythonOCC Xlib'): - self.d = display - self.objects = [] - self.viewer_inited = False - # Find which screen to open the window on - self.screen = self.d.screen() - self._function_list = [] - self._function_iterator = iter(self._function_list) - self.window = self.screen.root.create_window( - 50, 50, 640, 480, 2, - self.screen.root_depth, - X.InputOutput, - X.CopyFromParent, - event_mask = (X.ExposureMask | - X.StructureNotifyMask | - X.ButtonPressMask | - X.KeyPressMask| - X.ButtonReleaseMask | - X.PointerMotionMask | - X.ResizeRedirectMask) - ) - self.WM_DELETE_WINDOW = self.d.intern_atom('WM_DELETE_WINDOW') - self.WM_PROTOCOLS = self.d.intern_atom('WM_PROTOCOLS') - - self.window.set_wm_name(title) - #self.window.set_wm_icon_name('pythonOCC Xlib') - self.InitDriver() - self.window.map() - self._setup_keymap() - - def InitDriver(self): - self.occviewer = OCCViewer.Viewer3d(self.window.id) - self.occviewer.Create() - self.occviewer.DisplayTriedron() - self.occviewer.SetModeShaded() - #self.viewer_inited = True - - def register_function(self,function): - ''' Enable to call a function when the key "n" is hit - ''' - self._function_list.append(function) - self._function_iterator = iter(self._function_list) - self._setup_keymap() - print "Fuction %s registered"%function.__name__ - - def _setup_keymap(self): - def set_shade_mode(): - self.occviewer.DisableAntiAliasing() - self.occviewer.SetModeShaded() - self._key_map = { - ord('w'): self.occviewer.SetModeWireFrame, - ord('s'): set_shade_mode, - ord('a'): self.occviewer.EnableAntiAliasing, - ord('b'): self.occviewer.DisableAntiAliasing, - ord('q'): self.occviewer.SetModeQuickHLR, - ord('e'): self.occviewer.SetModeExactHLR, - ord('f'): self.occviewer.FitAll, - #ord('F'): self._display.ExportToImage("essai.BMP"), - ord('v'): self.occviewer.SetSelectionModeVertex, - ord('n'): self._function_iterator, - 65307:sys.exit#'ESC' hit - } - # Main MainLoop, handling events - def MainLoop(self): - current = None - while True: - e = self.d.next_event() - if not self.viewer_inited: - self.occviewer.OnResize() #need to be resized in ordre tohave a proper display - self.viewer_inited = True - # Window has been destroyed, quit - if e.type == X.DestroyNotify: - sys.exit(0) - # Some part of the window has been exposed, - # redraw all the objects. - elif e.type == X.Expose: - self.occviewer.OnResize() - # o.expose(e) - # Left button pressed, start to draw - elif e.type == X.ButtonPress and e.detail == 1: - current = MoveEvent(self, e) - #self.objects.append(current) - # Middle button pressed, start to draw - elif e.type == X.ButtonPress and e.detail == 2: - current = MoveEvent(self, e) - #self.objects.append(current) - elif e.type == X.ButtonPress and e.detail == 3: - current = MoveEvent(self, e) - #self.objects.append(current) - # Left button released - elif e.type == X.ButtonRelease and current:# and e.detail == 1 and current: - current.finish(e) - current = None - elif e.type == X.KeyPress: - key_code = self.d.keycode_to_keysym(e.detail, 0) - try: - if isinstance(self._key_map[key_code],type(iter([]))):#iterator type - self._key_map[key_code].next()() - else: - self._key_map[key_code]() - except: - print 'unrecognized key', key_code - # Mouse movement with button pressed - elif e.type == X.MotionNotify and current: - current.motion(e) - elif e.type == X.MotionNotify: - # Motion without any button pressed: selection mode - self.occviewer.MoveTo(e.event_x,e.event_y) - elif e.type == X.ClientMessage: - if e.client_type == self.WM_PROTOCOLS: - fmt, data = e.data - if fmt == 32 and data[0] == self.WM_DELETE_WINDOW: - sys.exit(0) - elif e.type == X.ResizeRequest: - self.window.map() - self.occviewer.OnResize() - elif e.type == X.ButtonRelease: - print "Button Release!!" - if self.occviewer.Select(e.event_x,e.event_y): - selected_shape = self.occviewer.GetSelectedShape() - print selected_shape,selected_shape.ShapeType() - -class MoveEvent: - def __init__(self, win, ev): - self.win = win - self.lastx = ev.event_x - self.lasty = ev.event_y - self.time = ev.time - self.last = None - self.event_time = ev.time - - def motion(self, ev): - events = self.win.window.get_motion_events(self.time, ev.time) - self.time = ev.time - delta_x = ev.event_x -self.lastx - delta_y = ev.event_y - self.lasty - self.lastx = ev.event_x - self.lasty = ev.event_y - self.win.occviewer.Rotation(ev.event_x,ev.event_y) - - def finish(self,ev): - self.end_time = ev.time - if self.end_time-self.event_time<200:#ms - if self.win.occviewer.Select(ev.event_x,ev.event_y): - selected_shape = self.win.occviewer.GetSelectedShape() - print selected_shape,selected_shape.ShapeType() - -def Test3d(): - d = display.Display() - w = XOCCWindow(d) - w.occviewer.Test() - w.MainLoop() - - -if __name__=="__main__": - Test3d() diff --git a/src/addons/Display/wxSamplesGui2d.py b/src/addons/Display/wxSamplesGui2d.py deleted file mode 100644 index f20dd4d86..000000000 --- a/src/addons/Display/wxSamplesGui2d.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python - -##Copyright 2009-2011 Jelle Feringa (jelleferinga@gmail.com) -## -##This file is part of pythonOCC. -## -##pythonOCC 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 3 of the License, or -##(at your option) any later version. -## -##pythonOCC 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 pythonOCC. If not, see . - -import wx, sys -from wxDisplay import wxViewer2d -from OCC import VERSION - -class AppFrame(wx.Frame): - def __init__(self, parent): - wx.Frame.__init__(self, parent, -1, "pythonOCC-%s 2d viewer"%VERSION, style=wx.DEFAULT_FRAME_STYLE,size = (640,480)) - self.canva = wxViewer2d(self) - self.menuBar = wx.MenuBar() - self._menus = {} - self._menu_methods = {} - - def add_menu(self, menu_name): - _menu = wx.Menu() - self.menuBar.Append(_menu, "&"+menu_name) - self.SetMenuBar(self.menuBar) - self._menus[menu_name]=_menu - - def add_function_to_menu(self, menu_name, _callable): - # point on curve - _id = wx.NewId() - assert callable(_callable), 'the function supplied isnt callable' - try: - self._menus[menu_name].Append(_id, _callable.__name__.replace('_', ' ').lower()) - except KeyError: - raise ValueError('the menu item %s doesnt exist' % (menu_name)) - self.Bind(wx.EVT_MENU, _callable, id=_id) - - -app = wx.PySimpleApp() -wx.InitAllImageHandlers() -frame = AppFrame(None) -frame.Show(True) -wx.SafeYield() -frame.canva.InitDriver() -app.SetTopWindow(frame) -display2d = frame.canva._display - -def add_menu(*args, **kwargs): - frame.add_menu(*args, **kwargs) - -def add_function_to_menu(*args, **kwargs): - frame.add_function_to_menu(*args, **kwargs) - -def start_display2d(): - ''' - call the mainloop - ''' - global app - app.MainLoop() - -if __name__ == '__main__': - from OCC.BRepPrimAPI import * - def sphere(event=None): - display.DisplayShape(BRepPrimAPI_MakeSphere(1).Shape()) - - def cube(event=None): - display.DisplayShape(BRepPrimAPI_MakeBox(1,1,1).Shape()) - - def exit(event=None): - sys.exit() - - add_menu('primitives') - add_function_to_menu('primitives', sphere) - add_function_to_menu('primitives', cube) - add_function_to_menu('primitives', exit) - StartDisplay() - - From cf4b516159345c98294f391e665b357a2785b3f4 Mon Sep 17 00:00:00 2001 From: jf--- Date: Thu, 25 Apr 2013 22:59:26 +0200 Subject: [PATCH 18/29] updated and polished the traits viewer to the current version of traits, 4.3 --- src/addons/Display/traitShapeEditor.py | 63 ++++++++++++++++++-------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/src/addons/Display/traitShapeEditor.py b/src/addons/Display/traitShapeEditor.py index bd87a1fa1..dcacc4713 100644 --- a/src/addons/Display/traitShapeEditor.py +++ b/src/addons/Display/traitShapeEditor.py @@ -19,24 +19,28 @@ # Draft implementation of a custom editor for Enthought Traits GUI, # simply assign the editor to a Traited list of Topo_DS shapes and off you go. -__author__ = 'Henrik Rudstrom' - -from enthought.traits.has_traits import HasTraits -from enthought.traits.ui.item import Item -from enthought.traits.ui.view import View -from enthought.traits.trait_types import Any, Button, List, Instance, Str, Bool -from enthought.traits.ui.editor import Editor -from enthought.traits.ui.editor_factory import EditorFactory + from itertools import izip +import random, os + +try: + if os.environ["ETS_TOOLKIT"] == "wx": + print "ETS_TOOLKIT variable has been set to wx, though this example explicitly uses the Qt backed\ + setting the backend to Qt4..." +except KeyError: + pass + +os.environ["ETS_TOOLKIT"] = "qt4" +# abstracts PyQt4 and PySide +from pyface.qt import QtGui + +from traits.api import HasTraits, Any, Button, List, Instance, Str, Bool +from traitsui.api import Item, View, EditorFactory, Editor from OCC.gp import gp_Trsf, gp_Vec from OCC.TopLoc import TopLoc_Location from OCC.Display.qtDisplay import qtViewer3d from OCC.BRepPrimAPI import BRepPrimAPI_MakeCylinder from OCC.Display import OCCViewer -from OCC import PAF -import OCC -import random -from PyQt4 import Qt class TraitOCCViewer3d(OCCViewer.Viewer3d): ''' @@ -55,6 +59,7 @@ def DisplayShape(self, shapes, **kwargs): ais = OCCViewer.Viewer3d.DisplayShape(self, shapes, **kwargs) self.ShapeMap[shapes] = ais + def EraseShape(self, shape): if shape not in self.ShapeMap: raise Exception("shape not in shapemap") @@ -69,7 +74,7 @@ def __init__(self, editor=None, selection=None, **kwargs): self.editor = editor self._initialized = False - self.setSizePolicy(Qt.QSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Expanding)); + self.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)); self.setMinimumHeight(100) self.setMinimumWidth(150) @@ -110,7 +115,7 @@ class OCCEditor(Editor): selection = List(Any) display = Instance(OCCViewer) initialized = Bool - + def init ( self, parent): self.control = OCCTraitViewer(self, self.selection) self.sync_value(self.name, 'shapes', 'both', is_list=True) @@ -118,12 +123,23 @@ def init ( self, parent): self.sync_value(self.factory.selection, 'selection', 'both', is_list=True) if self.factory.display: self.sync_value(self.factory.display, 'display', 'both') - + + def set_size_policy(self, *args, **kwargs): + """ + no idea what it does, but is called... + i guess should give some hints... + + :param args: + :param kwargs: + """ + pass + def _shapes_changed(self, name, nothing, change): '''update shapes when list is replaced''' self.control._display.EraseAll() for s in change: self.control._display.DisplayShape(s) + self.control._display.FitAll() def _shapes_items_changed(self, name, nothing, change): '''update display when the list is modified''' @@ -131,6 +147,7 @@ def _shapes_items_changed(self, name, nothing, change): self.control._display.DisplayShape(s) for s in change.removed: self.control._display.EraseShape(s) + self.control._display.FitAll() @@ -179,8 +196,16 @@ def _add_stuff_changed(self, old, new): self.shapes.append(brep) def _remove_stuff_changed(self, old, new): - for shape in self.selection: - self.shapes.remove(shape) - - + if len(self.selection) >= 1: + for shape in self.selection: + self.shapes.remove(shape) + self.selection = [] + else: + print "nothing selected so removing an arbitrary number of shapes" + for i in range(random.randint(1, 8)): + if len(self.shapes) > 0: + self.shapes.pop() + else: + print "you should add some if you want me to remove stuff..." + Example(shapes=[]).configure_traits() From 66171ee4489108d86541d95763a5bfbc7d5d56fa Mon Sep 17 00:00:00 2001 From: jf--- Date: Tue, 14 May 2013 00:09:32 +0200 Subject: [PATCH 19/29] merge with Thomas tree, a lot of cleanup --- src/addons/DataExchange/STL_fast.py | 21 +- src/addons/Display/OCCViewer.py | 35 +- src/addons/Display/SimpleGui.py | 38 +- src/addons/Display/WebGl/three.min.js | 1295 ++++++++++++------------- src/addons/Display/qtDisplay.py | 9 - src/addons/Display/wxDisplay.py | 22 +- src/addons/KBE/__init__.py | 4 - src/addons/KBE/base.py | 2 - src/addons/KBE/edge.py | 79 +- src/addons/KBE/face.py | 54 +- src/addons/KBE/plane.py | 9 - src/addons/KBE/scratchpad.py | 4 - src/addons/KBE/shell.py | 10 +- src/addons/KBE/solid.py | 12 +- src/addons/KBE/types_lut.py | 51 - src/addons/KBE/vertex.py | 22 +- src/addons/KBE/wire.py | 2 - src/addons/Utils/Common.py | 1 - src/addons/Utils/Construct.py | 1 - src/addons/Utils/Iteration.py | 2 - src/addons/Utils/Topology.py | 2 +- 21 files changed, 673 insertions(+), 1002 deletions(-) diff --git a/src/addons/DataExchange/STL_fast.py b/src/addons/DataExchange/STL_fast.py index 500e16aef..fdc42b306 100644 --- a/src/addons/DataExchange/STL_fast.py +++ b/src/addons/DataExchange/STL_fast.py @@ -1,9 +1,13 @@ import os from OCC.RWStl import RWStl -from OCC.MeshVS import MeshVS_Mesh from OCC.OSD import OSD_Path from OCC.TCollection import TCollection_AsciiString - +from OCC.Graphic3d import Graphic3d_MaterialAspect, Graphic3d_NOM_SATIN +from OCC.MeshVS import MeshVS_Mesh, MeshVS_MeshPrsBuilder, MeshVS_DA_FrontMaterial, MeshVS_DA_DisplayNodes, MeshVS_DA_ShowEdges, MeshVS_DA_SmoothShading, MeshVS_DA_Reflection +try: + from OCC.SMESH import SMESH_Gen, SMESH_MeshVSLink +except ImportError: + raise AssertionError("SMESH wrapper is required to use the STL_fast module") #=============================================================================== # Currently -alas- the fast STL mesh loader relies on SMESH as a dependency @@ -45,14 +49,6 @@ # # myDoc->m_AISContext->Display(aMesh); - - -import os -from OCC.Graphic3d import Graphic3d_MaterialAspect, Graphic3d_NOM_SATIN -from OCC.MeshVS import MeshVS_Mesh, MeshVS_MeshPrsBuilder, MeshVS_DA_FrontMaterial, MeshVS_DA_DisplayNodes, MeshVS_DA_ShowEdges, MeshVS_DA_SmoothShading, MeshVS_DA_Reflection -from OCC.SMESH import SMESH_Gen, SMESH_MeshVSLink - - def get_fast_stl_mesh_from_path(_path): """ open/parse STL file and get the resulting TopoDS_Shape instance @@ -66,7 +62,6 @@ def get_fast_stl_mesh_from_path(_path): # test for a minimal number of mesh vertices if mesh.NbNodes() < 1: raise ValueError("stl file {0} contains no geometry".format(_path)) - aDS = SMESH_MeshVSLink(mesh) aMeshVS = MeshVS_Mesh(True) DMF = 2 # to wrap; 1 is wireframe @@ -89,16 +84,12 @@ def get_fast_stl_mesh_from_path(_path): # mesh_drawer.SetColor(3,Quantity_Color(Quantity_NOC_BLACK))# 3 means Edge color # Markers in green # mesh_drawer.SetColor(13,Quantity_Color(Quantity_NOC_GREEN)) - print 'got it, just setting params' mesh_drawer.SetMaterial(MeshVS_DA_FrontMaterial, Graphic3d_MaterialAspect(Graphic3d_NOM_SATIN)) mesh_drawer.SetBoolean( MeshVS_DA_DisplayNodes, False) mesh_drawer.SetBoolean( MeshVS_DA_ShowEdges, False) mesh_drawer.SetBoolean( MeshVS_DA_SmoothShading, True) -# mesh_drawer.SetBoolean( MeshVS_DA_SmoothShading, False) mesh_drawer.SetBoolean( MeshVS_DA_Reflection, True) # mesh_drawer.SetColor( MeshVS_DA_InteriorColor, Quantity_Color(Quantity_NOC_AZURE)) # mesh_drawer.SetBoolean(MeshVS_DA_ColorReflection, True) msh = mesh_to_display.GetObject() - print 'msh:', msh return msh - diff --git a/src/addons/Display/OCCViewer.py b/src/addons/Display/OCCViewer.py index 5807dcdec..3f793b05b 100644 --- a/src/addons/Display/OCCViewer.py +++ b/src/addons/Display/OCCViewer.py @@ -29,9 +29,7 @@ from OCC.KBE.types_lut import topo_lut import OCC.Visualization import OCC.V3d -import OCC.V2d import OCC.AIS -import OCC.AIS2D import OCC.Quantity import OCC.TopoDS import OCC.Visual3d @@ -40,8 +38,6 @@ from OCC.Quantity import Quantity_Color, Quantity_NOC_ORANGE from OCC.Graphic3d import Graphic3d_NOM_SATIN - - def set_CSF_GraphicShr(): "Sets the CSF_GraphicShr env var" from ctypes import util @@ -50,14 +46,12 @@ def set_CSF_GraphicShr(): if not (sys.platform == 'win32'): set_CSF_GraphicShr() - modes = itertools.cycle([TopAbs.TopAbs_FACE, TopAbs.TopAbs_EDGE, TopAbs.TopAbs_VERTEX, TopAbs.TopAbs_SHELL, TopAbs.TopAbs_SOLID, ]) - class BaseDriver(object): """ - The base driver class for both Driver2d and Driver3d classes + The base driver class """ def __init__(self, window_handle): self._window_handle = window_handle @@ -76,12 +70,8 @@ def MoveTo(self,X,Y): self.Context.MoveTo(X,Y,self.View_handle) def FitAll(self): - if hasattr(self.View, 'Fitall'): - # Viewer2d - self.View.Fitall() - else: - self.View.ZFitAll() - self.View.FitAll() + self.View.ZFitAll() + self.View.FitAll() def SetWindow(self,window_handle): self._window_handle = window_handle @@ -99,12 +89,8 @@ def Create(self, create_default_lights = True): self.Context = self.Context_handle.GetObject() self.Viewer = self.Viewer_handle.GetObject() if create_default_lights: - try: - self.Viewer.SetDefaultLights() - self.Viewer.SetLightOn() - except AttributeError: - # Viewer2d doesnt have SetDefaultLights attr - pass + self.Viewer.SetDefaultLights() + self.Viewer.SetLightOn() self.View = self.View_handle.GetObject() self._inited = True # some preferences; @@ -112,13 +98,7 @@ def Create(self, create_default_lights = True): self.Context.SelectionColor(Quantity_NOC_ORANGE) # nessecary for text rendering - try: - self._struc_mgr = self.Context.MainPrsMgr().GetObject().StructureManager() - except AttributeError: - # Viewer2d doesnt have MainPrsMgr attr - pass - - + self._struc_mgr = self.Context.MainPrsMgr().GetObject().StructureManager() class Viewer3d(BaseDriver, OCC.Visualization.Display3d): def __init__(self, window_handle ): @@ -371,7 +351,7 @@ def SetSelectionMode(self, mode=None): else: self.Context.ActivateStandardMode(mode) self.Context.UpdateSelected() - + def SetSelectionModeShape(self): self.Context.CloseAllContexts() @@ -438,4 +418,3 @@ def Zoom(self,X,Y): def StartRotation(self,X,Y): self.View.StartRotation(X,Y) - diff --git a/src/addons/Display/SimpleGui.py b/src/addons/Display/SimpleGui.py index b0453b6ad..3e888de70 100644 --- a/src/addons/Display/SimpleGui.py +++ b/src/addons/Display/SimpleGui.py @@ -51,13 +51,8 @@ def get_backend(): except: pass - if sys.platform == 'darwin': - # Tk is not an option, since we on osx a modern Cocoa backend is required - raise ValueError("PythonOCC needs PySide of PyQt4 as a gui backend. wxPython 2.9, using cocoa is an option, but not recommended") - + # use Tk backend as a fall back... else: - # use Tk backend as a fall back... - # note, this is X11 territory, so no go area for osx... since this relies on the Cocoa backend try: import Tkinter return 'tkinter' @@ -75,25 +70,16 @@ def get_bg_abs_filename(): else: return bg_abs_filename -def safe_yield(): - global USED_BACKEND - if USED_BACKEND == 'wx': - import wx - wx.SafeYield() - elif USED_BACKEND == 'pyqt4': - from PyQt4 import QtGui - #QtCore.processEvents() - QtGui.QApplication.processEvents() - elif USED_BACKEND == 'pyside': - from PySide import QtGui - #QtCore.processEvents() - QtGui.QApplication.processEvents() - -def init_display(): +def init_display(backend_str = None): global display, add_menu, add_function_to_menu, start_display, app, win, USED_BACKEND - USED_BACKEND = get_backend() - + if not backend_str: + USED_BACKEND = get_backend() + elif backend_str in ['wx','pyqt4','pyside','tkinter']: + USED_BACKEND = backend_str + else: + raise ValueError("You should pass either 'wx','pyqt4','pyside' or'tkinter' to the init_display function.") + sys.exit(1) # wxPython based simple GUI if USED_BACKEND == 'wx': import wx @@ -141,7 +127,7 @@ def start_display(): elif USED_BACKEND == 'pyqt4' or USED_BACKEND=='pyside': # dont really get why its nessecary to import yet again... sigh... - if USED_BACKEND == "pyqt4": + if USED_BACKEND == 'pyqt4': from PyQt4 import QtGui, QtCore else: from PySide import QtGui, QtCore @@ -205,7 +191,7 @@ def start_display(): win.raise_() # make the application float to the top app.exec_() - elif USED_BACKEND == 'Tk': + elif USED_BACKEND == 'tkinter': import Tkinter from tkDisplay import tkViewer3d app = Tkinter.Tk() @@ -221,7 +207,7 @@ def add_function_to_menu(*args, **kwargs): return display, start_display, add_menu, add_function_to_menu if __name__ == '__main__': - init_display() + init_display('tkinter') from OCC.BRepPrimAPI import * def sphere(event=None): display.DisplayShape(BRepPrimAPI_MakeSphere(1).Shape(), update=True) diff --git a/src/addons/Display/WebGl/three.min.js b/src/addons/Display/WebGl/three.min.js index 103e921d8..9f9b82b68 100644 --- a/src/addons/Display/WebGl/three.min.js +++ b/src/addons/Display/WebGl/three.min.js @@ -1,557 +1,553 @@ // three.js - http://github.com/mrdoob/three.js -'use strict';var THREE=THREE||{REVISION:"53"};self.console=self.console||{info:function(){},log:function(){},debug:function(){},warn:function(){},error:function(){}};self.Int32Array=self.Int32Array||Array;self.Float32Array=self.Float32Array||Array;String.prototype.startsWith=String.prototype.startsWith||function(a){return this.slice(0,a.length)===a};String.prototype.endsWith=String.prototype.endsWith||function(a){var a=String(a),b=this.lastIndexOf(a);return(-1>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getContextStyle:function(){return"rgb("+(255*this.r|0)+","+(255*this.g|0)+","+(255*this.b|0)+")"},setContextStyle:function(a){a=/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/i.exec(a);this.r=parseInt(a[1],10)/255;this.g=parseInt(a[2],10)/255;this.b=parseInt(a[3],10)/255;return this},getHSV:function(a){var b= -this.r,c=this.g,d=this.b,e=Math.max(Math.max(b,c),d),f=Math.min(Math.min(b,c),d);if(f===e)f=b=0;else{var g=e-f,f=g/e,b=(b===e?(c-d)/g:c===e?2+(d-b)/g:4+(b-c)/g)/6;0>b&&(b+=1);1Math.abs(g)?(this.x=Math.atan2(-j,d),this.z=Math.atan2(-f,e)):(this.x=Math.atan2(m,i),this.z=0)):"YXZ"===b?(this.x=Math.asin(-c(j)),0.99999>Math.abs(j)? -(this.y=Math.atan2(g,d),this.z=Math.atan2(h,i)):(this.y=Math.atan2(-l,e),this.z=0)):"ZXY"===b?(this.x=Math.asin(c(m)),0.99999>Math.abs(m)?(this.y=Math.atan2(-l,d),this.z=Math.atan2(-f,i)):(this.y=0,this.z=Math.atan2(h,e))):"ZYX"===b?(this.y=Math.asin(-c(l)),0.99999>Math.abs(l)?(this.x=Math.atan2(m,d),this.z=Math.atan2(h,e)):(this.x=0,this.z=Math.atan2(-f,i))):"YZX"===b?(this.z=Math.asin(c(h)),0.99999>Math.abs(h)?(this.x=Math.atan2(-j,i),this.y=Math.atan2(-l,e)):(this.x=0,this.y=Math.atan2(g,d))): -"XZY"===b&&(this.z=Math.asin(-c(f)),0.99999>Math.abs(f)?(this.x=Math.atan2(m,i),this.y=Math.atan2(g,e)):(this.x=Math.atan2(-j,d),this.y=0));return this},setEulerFromQuaternion:function(a,b){function c(a){return Math.min(Math.max(a,-1),1)}var d=a.x*a.x,e=a.y*a.y,f=a.z*a.z,g=a.w*a.w;void 0===b||"XYZ"===b?(this.x=Math.atan2(2*(a.x*a.w-a.y*a.z),g-d-e+f),this.y=Math.asin(c(2*(a.x*a.z+a.y*a.w))),this.z=Math.atan2(2*(a.z*a.w-a.x*a.y),g+d-e-f)):"YXZ"===b?(this.x=Math.asin(c(2*(a.x*a.w-a.y*a.z))),this.y=Math.atan2(2* -(a.x*a.z+a.y*a.w),g-d-e+f),this.z=Math.atan2(2*(a.x*a.y+a.z*a.w),g-d+e-f)):"ZXY"===b?(this.x=Math.asin(c(2*(a.x*a.w+a.y*a.z))),this.y=Math.atan2(2*(a.y*a.w-a.z*a.x),g-d-e+f),this.z=Math.atan2(2*(a.z*a.w-a.x*a.y),g-d+e-f)):"ZYX"===b?(this.x=Math.atan2(2*(a.x*a.w+a.z*a.y),g-d-e+f),this.y=Math.asin(c(2*(a.y*a.w-a.x*a.z))),this.z=Math.atan2(2*(a.x*a.y+a.z*a.w),g+d-e-f)):"YZX"===b?(this.x=Math.atan2(2*(a.x*a.w-a.z*a.y),g-d+e-f),this.y=Math.atan2(2*(a.y*a.w-a.x*a.z),g+d-e-f),this.z=Math.asin(c(2*(a.x*a.y+ -a.z*a.w)))):"XZY"===b&&(this.x=Math.atan2(2*(a.x*a.w+a.y*a.z),g-d+e-f),this.y=Math.atan2(2*(a.x*a.z+a.y*a.w),g+d-e-f),this.z=Math.asin(c(2*(a.z*a.w-a.x*a.y))));return this},getScaleFromMatrix:function(a){var b=this.set(a.elements[0],a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5],a.elements[6]).length(),a=this.set(a.elements[8],a.elements[9],a.elements[10]).length();this.x=b;this.y=c;this.z=a;return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z}, -clone:function(){return new THREE.Vector3(this.x,this.y,this.z)}};THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; -THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},sub:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},subSelf:function(a){this.x-= -a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},divideScalar:function(a){a?(this.x/=a,this.y/=a,this.z/=a,this.w/=a):(this.z=this.y=this.x=0,this.w=1);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.dot(this)},length:function(){return Math.sqrt(this.lengthSq())},lengthManhattan:function(){return Math.abs(this.x)+ -Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.normalize().multiplyScalar(a)},lerpSelf:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0): -(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d,a=a.elements,e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],i=a[9];c=a[2];b=a[6];var j=a[10];if(0.01>Math.abs(d-g)&&0.01>Math.abs(f-c)&&0.01>Math.abs(i-b)){if(0.1>Math.abs(d+g)&&0.1>Math.abs(f+c)&&0.1>Math.abs(i+b)&&0.1>Math.abs(e+h+j-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;j=(j+1)/2;d=(d+g)/4;f=(f+c)/4;i=(i+b)/4;e>h&&e>j?0.01>e?(b=0,d=c=0.707106781):(b=Math.sqrt(e),c=d/b,d=f/ -b):h>j?0.01>h?(b=0.707106781,c=0,d=0.707106781):(c=Math.sqrt(h),b=d/c,d=i/c):0.01>j?(c=b=0.707106781,d=0):(d=Math.sqrt(j),b=f/d,c=i/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-i)*(b-i)+(f-c)*(f-c)+(g-d)*(g-d));0.001>Math.abs(a)&&(a=1);this.x=(b-i)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+j-1)/2);return this}};THREE.Matrix3=function(){this.elements=new Float32Array(9)}; -THREE.Matrix3.prototype={constructor:THREE.Matrix3,multiplyVector3:function(a){var b=this.elements,c=a.x,d=a.y,e=a.z;a.x=b[0]*c+b[3]*d+b[6]*e;a.y=b[1]*c+b[4]*d+b[7]*e;a.z=b[2]*c+b[5]*d+b[8]*e;return a},multiplyVector3Array:function(a){for(var b=THREE.Matrix3.__v1,c=0,d=a.length;cd;d++)a=b[d],a.divideScalar(Math.sqrt(a.x*a.x+a.y*a.y+a.z*a.z))}; -THREE.Frustum.prototype.contains=function(a){for(var b=0,c=this.planes,b=a.matrixWorld,d=b.elements,a=-a.geometry.boundingSphere.radius*b.getMaxScaleOnAxis(),e=0;6>e;e++)if(b=c[e].x*d[12]+c[e].y*d[13]+c[e].z*d[14]+c[e].w,b<=a)return!1;return!0};THREE.Frustum.__v1=new THREE.Vector3; -(function(a){a.Ray=function(b,c,d,e){this.origin=b||new a.Vector3;this.direction=c||new a.Vector3;this.near=d||0;this.far=e||Infinity};var b=new a.Vector3,c=new a.Vector3,d=new a.Vector3,e=new a.Vector3;new a.Vector3;var f=new a.Vector3,g=new a.Matrix4,h=function(a,b){return a.distance-b.distance},i=new a.Vector3,j=new a.Vector3,l=new a.Vector3,m=function(a,b,c){i.sub(c,a);var d=i.dot(b),a=j.add(a,l.copy(b).multiplyScalar(d));return c.distanceTo(a)},n=function(a,b,c,d){i.sub(d,b);j.sub(c,b);l.sub(a, -b);var a=i.dot(i),b=i.dot(j),c=i.dot(l),e=j.dot(j),d=j.dot(l),f=1/(a*e-b*b),e=(e*c-b*d)*f,a=(a*d-b*c)*f;return 0<=e&&0<=a&&1>e+a},p=function(h,i,j){if(h instanceof a.Particle){var l=m(i.origin,i.direction,h.matrixWorld.getPosition());if(l>h.scale.x)return j;j.push({distance:l,point:h.position,face:null,object:h})}else if(h instanceof a.Mesh){var o=h.geometry.boundingSphere.radius*h.matrixWorld.getMaxScaleOnAxis(),l=m(i.origin,i.direction,h.matrixWorld.getPosition());if(l>o)return j;var o=h.geometry, -p=o.vertices,E=h.material instanceof a.MeshFaceMaterial,A=!0===E?h.material.materials:null,l=h.material.side,v,u,D,C=i.precision;h.matrixRotationWorld.extractRotation(h.matrixWorld);b.copy(i.origin);g.getInverse(h.matrixWorld);c.copy(b);g.multiplyVector3(c);d.copy(i.direction);g.rotateAxis(d).normalize();for(var G=0,P=o.faces.length;G -u)&&(l===a.DoubleSide||(l===a.FrontSide?0>v:0i.far||j.push({distance:l,point:v,face:B,faceIndex:G,object:h}));else if(B instanceof a.Face4&&(l=p[B.a],v=p[B.b],u=p[B.c],D=p[B.d],n(f,l,v,D)||n(f,v,u,D)))v=h.matrixWorld.multiplyVector3(f.clone()),l=b.distanceTo(v),li.far||j.push({distance:l,point:v,face:B,faceIndex:G,object:h})}}}, -o=function(a,b,c){for(var a=a.getDescendants(),d=0,e=a.length;df?d:f,e=e> -g?e:g);a()};this.add3Points=function(f,g,l,m,n,p){!0===h?(h=!1,b=fl?f>n?f:n:l>n?l:n,e=g>m?g>p?g:p:m>p?m:p):(b=fl?f>n?f>d?f:d:n>d?n:d:l>n?l>d?l:d:n>d?n:d,e=g>m?g>p?g>e?g:e:p>e?p:e:m>p?m>e?m:e:p>e?p:e);a()};this.addRectangle=function(f){!0===h?(h=!1,b=f.getLeft(),c=f.getTop(),d=f.getRight(),e=f.getBottom()):(b=bf.getRight()?d:f.getRight(),e=e>f.getBottom()?e:f.getBottom());a()};this.inflate=function(f){b-=f;c-=f;d+=f;e+=f;a()};this.minSelf=function(f){b=b>f.getLeft()?b:f.getLeft();c=c>f.getTop()?c:f.getTop();d=da.getRight()||ea.getBottom()?!1:!0};this.empty=function(){h=!0;e=d=c=b=0;a()};this.isEmpty=function(){return h}}; -THREE.Math={clamp:function(a,b,c){return ac?c:a},clampBottom:function(a,b){return aa?-1:0e&&0>f||0>g&&0>h)return!1;0>e?c=Math.max(c,e/(e-f)):0>f&&(d=Math.min(d,e/(e-f)));0>g?c=Math.max(c,g/(g-h)):0>h&&(d=Math.min(d,g/(g-h)));if(d< -c)return!1;a.lerpSelf(b,c);b.lerpSelf(a,1-d);return!0}var e,f,g=[],h=0,i,j,l=[],m=0,n,p,o=[],s=0,t,r=[],z=0,w,q,E=[],A=0,v,u,D=[],C=0,G={objects:[],sprites:[],lights:[],elements:[]},P=new THREE.Vector3,B=new THREE.Vector4,K=new THREE.Matrix4,H=new THREE.Matrix4,I=new THREE.Matrix3,N=new THREE.Frustum,O=new THREE.Vector4,R=new THREE.Vector4;this.projectVector=function(a,b){b.matrixWorldInverse.getInverse(b.matrixWorld);K.multiply(b.projectionMatrix,b.matrixWorldInverse);K.multiplyVector3(a);return a}; -this.unprojectVector=function(a,b){b.projectionMatrixInverse.getInverse(b.projectionMatrix);K.multiply(b.matrixWorld,b.projectionMatrixInverse);K.multiplyVector3(a);return a};this.pickingRay=function(a,b){var c;a.z=-1;c=new THREE.Vector3(a.x,a.y,1);this.unprojectVector(a,b);this.unprojectVector(c,b);c.subSelf(a).normalize();return new THREE.Ray(a,c)};this.projectScene=function(g,h,m,Q){var Z=h.near,L=h.far,oa=!1,X,fa,ca,Y,ba,aa,ia,Aa,Na,Ja,ma,sa,Ea,rb,ib;u=q=t=p=0;G.elements.length=0;g.updateMatrixWorld(); -void 0===h.parent&&h.updateMatrixWorld();h.matrixWorldInverse.getInverse(h.matrixWorld);K.multiply(h.projectionMatrix,h.matrixWorldInverse);N.setFromMatrix(K);f=0;G.objects.length=0;G.sprites.length=0;G.lights.length=0;var ob=function(b){for(var c=0,d=b.children.length;cZ&&i.positionScreen.z(ia.positionScreen.x-Y.positionScreen.x)*(ba.positionScreen.y-Y.positionScreen.y)-(ia.positionScreen.y-Y.positionScreen.y)*(ba.positionScreen.x-Y.positionScreen.x),aa===THREE.DoubleSide||oa===(aa===THREE.FrontSide))p=== -s?(sa=new THREE.RenderableFace3,o.push(sa),s++,p++,n=sa):n=o[p++],n.v1.copy(Y),n.v2.copy(ba),n.v3.copy(ia);else continue;else continue;else if(fa instanceof THREE.Face4)if(Y=l[fa.a],ba=l[fa.b],ia=l[fa.c],sa=l[fa.d],!0===Y.visible&&!0===ba.visible&&!0===ia.visible&&!0===sa.visible)if(oa=0>(sa.positionScreen.x-Y.positionScreen.x)*(ba.positionScreen.y-Y.positionScreen.y)-(sa.positionScreen.y-Y.positionScreen.y)*(ba.positionScreen.x-Y.positionScreen.x)||0>(ba.positionScreen.x-ia.positionScreen.x)*(sa.positionScreen.y- -ia.positionScreen.y)-(ba.positionScreen.y-ia.positionScreen.y)*(sa.positionScreen.x-ia.positionScreen.x),aa===THREE.DoubleSide||oa===(aa===THREE.FrontSide)){if(t===z){var jb=new THREE.RenderableFace4;r.push(jb);z++;t++;n=jb}else n=r[t++];n.v1.copy(Y);n.v2.copy(ba);n.v3.copy(ia);n.v4.copy(sa)}else continue;else continue;n.normalWorld.copy(fa.normal);!1===oa&&(aa===THREE.BackSide||aa===THREE.DoubleSide)&&n.normalWorld.negate();I.multiplyVector3(n.normalWorld).normalize();n.centroidWorld.copy(fa.centroid); -Na.multiplyVector3(n.centroidWorld);n.centroidScreen.copy(n.centroidWorld);K.multiplyVector3(n.centroidScreen);ia=fa.vertexNormals;Y=0;for(ba=ia.length;YB.z&&(u===C?(Z=new THREE.RenderableParticle,D.push(Z),C++,u++,v=Z):v=D[u++],v.object=Aa,v.x=B.x/B.w,v.y=B.y/B.w,v.z=B.z,v.rotation=Aa.rotation.z,v.scale.x=Aa.scale.x*Math.abs(v.x- -(B.x+h.projectionMatrix.elements[0])/(B.w+h.projectionMatrix.elements[12])),v.scale.y=Aa.scale.y*Math.abs(v.y-(B.y+h.projectionMatrix.elements[5])/(B.w+h.projectionMatrix.elements[13])),v.material=Aa.material,G.elements.push(v)));!0===Q&&G.elements.sort(c);return G}};THREE.Quaternion=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; +function(a){window.clearTimeout(a)}})();THREE.CullFaceNone=0;THREE.CullFaceBack=1;THREE.CullFaceFront=2;THREE.CullFaceFrontBack=3;THREE.FrontFaceDirectionCW=0;THREE.FrontFaceDirectionCCW=1;THREE.BasicShadowMap=0;THREE.PCFShadowMap=1;THREE.PCFSoftShadowMap=2;THREE.FrontSide=0;THREE.BackSide=1;THREE.DoubleSide=2;THREE.NoShading=0;THREE.FlatShading=1;THREE.SmoothShading=2;THREE.NoColors=0;THREE.FaceColors=1;THREE.VertexColors=2;THREE.NoBlending=0;THREE.NormalBlending=1;THREE.AdditiveBlending=2; +THREE.SubtractiveBlending=3;THREE.MultiplyBlending=4;THREE.CustomBlending=5;THREE.AddEquation=100;THREE.SubtractEquation=101;THREE.ReverseSubtractEquation=102;THREE.ZeroFactor=200;THREE.OneFactor=201;THREE.SrcColorFactor=202;THREE.OneMinusSrcColorFactor=203;THREE.SrcAlphaFactor=204;THREE.OneMinusSrcAlphaFactor=205;THREE.DstAlphaFactor=206;THREE.OneMinusDstAlphaFactor=207;THREE.DstColorFactor=208;THREE.OneMinusDstColorFactor=209;THREE.SrcAlphaSaturateFactor=210;THREE.MultiplyOperation=0; +THREE.MixOperation=1;THREE.AddOperation=2;THREE.UVMapping=function(){};THREE.CubeReflectionMapping=function(){};THREE.CubeRefractionMapping=function(){};THREE.SphericalReflectionMapping=function(){};THREE.SphericalRefractionMapping=function(){};THREE.RepeatWrapping=1E3;THREE.ClampToEdgeWrapping=1001;THREE.MirroredRepeatWrapping=1002;THREE.NearestFilter=1003;THREE.NearestMipMapNearestFilter=1004;THREE.NearestMipMapLinearFilter=1005;THREE.LinearFilter=1006;THREE.LinearMipMapNearestFilter=1007; +THREE.LinearMipMapLinearFilter=1008;THREE.UnsignedByteType=1009;THREE.ByteType=1010;THREE.ShortType=1011;THREE.UnsignedShortType=1012;THREE.IntType=1013;THREE.UnsignedIntType=1014;THREE.FloatType=1015;THREE.UnsignedShort4444Type=1016;THREE.UnsignedShort5551Type=1017;THREE.UnsignedShort565Type=1018;THREE.AlphaFormat=1019;THREE.RGBFormat=1020;THREE.RGBAFormat=1021;THREE.LuminanceFormat=1022;THREE.LuminanceAlphaFormat=1023;THREE.RGB_S3TC_DXT1_Format=2001;THREE.RGBA_S3TC_DXT1_Format=2002; +THREE.RGBA_S3TC_DXT3_Format=2003;THREE.RGBA_S3TC_DXT5_Format=2004;THREE.Color=function(a){void 0!==a&&this.set(a);return this}; +THREE.Color.prototype={constructor:THREE.Color,r:1,g:1,b:1,set:function(a){a instanceof THREE.Color?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setHex:function(a){a=Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){if(0===b)this.r=this.g=this.b=c;else{var d=function(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a},b=0.5>=c?c*(1+b):c+b-c*b,c=2*c-b;this.r=d(c,b,a+1/3);this.g=d(c,b,a);this.b=d(c,b,a-1/3)}return this},setStyle:function(a){if(/^rgb\((\d+),(\d+),(\d+)\)$/i.test(a))return a=/^rgb\((\d+),(\d+),(\d+)\)$/i.exec(a),this.r=Math.min(255,parseInt(a[1],10))/255,this.g=Math.min(255,parseInt(a[2],10))/255,this.b=Math.min(255,parseInt(a[3],10))/255,this;if(/^rgb\((\d+)\%,(\d+)\%,(\d+)\%\)$/i.test(a))return a=/^rgb\((\d+)\%,(\d+)\%,(\d+)\%\)$/i.exec(a),this.r=Math.min(100, +parseInt(a[1],10))/100,this.g=Math.min(100,parseInt(a[2],10))/100,this.b=Math.min(100,parseInt(a[3],10))/100,this;if(/^\#([0-9a-f]{6})$/i.test(a))return a=/^\#([0-9a-f]{6})$/i.exec(a),this.setHex(parseInt(a[1],16)),this;if(/^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.test(a))return a=/^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(a),this.setHex(parseInt(a[1]+a[1]+a[2]+a[2]+a[3]+a[3],16)),this;if(/^(\w+)$/i.test(a))return this.setHex(THREE.ColorKeywords[a]),this},copy:function(a){this.r=a.r;this.g=a.g;this.b= +a.b;return this},copyGammaToLinear:function(a){this.r=a.r*a.r;this.g=a.g*a.g;this.b=a.b*a.b;return this},copyLinearToGamma:function(a){this.r=Math.sqrt(a.r);this.g=Math.sqrt(a.g);this.b=Math.sqrt(a.b);return this},convertGammaToLinear:function(){var a=this.r,b=this.g,c=this.b;this.r=a*a;this.g=b*b;this.b=c*c;return this},convertLinearToGamma:function(){this.r=Math.sqrt(this.r);this.g=Math.sqrt(this.g);this.b=Math.sqrt(this.b);return this},getHex:function(){return 255*this.r<<16^255*this.g<<8^255* +this.b<<0},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getHSL:function(){var a={h:0,s:0,l:0};return function(){var b=this.r,c=this.g,d=this.b,e=Math.max(b,c,d),f=Math.min(b,c,d),g,h=(f+e)/2;if(f===e)f=g=0;else{var i=e-f,f=0.5>=h?i/(e+f):i/(2-e-f);switch(e){case b:g=(c-d)/i+(cf&&c>b?(c=2*Math.sqrt(1+c-f-b),this.w=(i-g)/c,this.x=0.25*c,this.y=(a+e)/c,this.z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this.w=(d-h)/c,this.x=(a+e)/c,this.y=0.25*c,this.z=(g+i)/c):(c=2*Math.sqrt(1+b-c-f),this.w=(e-a)/c,this.x=(d+h)/c,this.y=(g+i)/c,this.z=0.25*c);return this},inverse:function(){this.conjugate().normalize(); -return this},conjugate:function(){this.x*=-1;this.y*=-1;this.z*=-1;return this},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},normalize:function(){var a=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);0===a?(this.z=this.y=this.x=0,this.w=1):(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a);return this},multiply:function(a,b){var c=a.x,d=a.y,e=a.z,f=a.w,g=b.x,h=b.y,i=b.z,j=b.w;this.x=c*j+d*i-e*h+f*g;this.y=-c*i+d*j+e*g+f*h;this.z=c*h- -d*g+e*j+f*i;this.w=-c*g-d*h-e*i+f*j;return this},multiplySelf:function(a){var b=this.x,c=this.y,d=this.z,e=this.w,f=a.x,g=a.y,h=a.z,a=a.w;this.x=b*a+e*f+c*h-d*g;this.y=c*a+e*g+d*f-b*h;this.z=d*a+e*h+b*g-c*f;this.w=e*a-b*f-c*g-d*h;return this},multiplyVector3:function(a,b){b||(b=a);var c=a.x,d=a.y,e=a.z,f=this.x,g=this.y,h=this.z,i=this.w,j=i*c+g*e-h*d,l=i*d+h*c-f*e,m=i*e+f*d-g*c,c=-f*c-g*d-h*e;b.x=j*i+c*-f+l*-h-m*-g;b.y=l*i+c*-g+m*-f-j*-h;b.z=m*i+c*-h+j*-g-l*-f;return b},slerpSelf:function(a,b){var c= -this.x,d=this.y,e=this.z,f=this.w,g=f*a.w+c*a.x+d*a.y+e*a.z;0>g?(this.w=-a.w,this.x=-a.x,this.y=-a.y,this.z=-a.z,g=-g):this.copy(a);if(1<=g)return this.w=f,this.x=c,this.y=d,this.z=e,this;var h=Math.acos(g),i=Math.sqrt(1-g*g);if(0.001>Math.abs(i))return this.w=0.5*(f+this.w),this.x=0.5*(c+this.x),this.y=0.5*(d+this.y),this.z=0.5*(e+this.z),this;g=Math.sin((1-b)*h)/i;h=Math.sin(b*h)/i;this.w=f*g+this.w*h;this.x=c*g+this.x*h;this.y=d*g+this.y*h;this.z=e*g+this.z*h;return this},clone:function(){return new THREE.Quaternion(this.x, -this.y,this.z,this.w)}};THREE.Quaternion.slerp=function(a,b,c,d){var e=a.w*b.w+a.x*b.x+a.y*b.y+a.z*b.z;0>e?(c.w=-b.w,c.x=-b.x,c.y=-b.y,c.z=-b.z,e=-e):c.copy(b);if(1<=Math.abs(e))return c.w=a.w,c.x=a.x,c.y=a.y,c.z=a.z,c;var b=Math.acos(e),f=Math.sqrt(1-e*e);if(0.001>Math.abs(f))return c.w=0.5*(a.w+c.w),c.x=0.5*(a.x+c.x),c.y=0.5*(a.y+c.y),c.z=0.5*(a.z+c.z),c;e=Math.sin((1-d)*b)/f;d=Math.sin(d*b)/f;c.w=a.w*e+c.w*d;c.x=a.x*e+c.x*d;c.y=a.y*e+c.y*d;c.z=a.z*e+c.z*d;return c}; -THREE.Vertex=function(a){console.warn("THREE.Vertex has been DEPRECATED. Use THREE.Vector3 instead.");return a};THREE.Face3=function(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d instanceof THREE.Vector3?d:new THREE.Vector3;this.vertexNormals=d instanceof Array?d:[];this.color=e instanceof THREE.Color?e:new THREE.Color;this.vertexColors=e instanceof Array?e:[];this.vertexTangents=[];this.materialIndex=f;this.centroid=new THREE.Vector3}; +return this},conjugate:function(){this.x*=-1;this.y*=-1;this.z*=-1;return this},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},normalize:function(){var a=this.length();0===a?(this.z=this.y=this.x=0,this.w=1):(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a);return this},multiply:function(a,b){return void 0!==b?(console.warn("DEPRECATED: Quaternion's .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."), +this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},multiplyQuaternions:function(a,b){var c=a.x,d=a.y,e=a.z,f=a.w,g=b.x,h=b.y,i=b.z,j=b.w;this.x=c*j+f*g+d*i-e*h;this.y=d*j+f*h+e*g-c*i;this.z=e*j+f*i+c*h-d*g;this.w=f*j-c*g-d*h-e*i;return this},multiplyVector3:function(a){console.warn("DEPRECATED: Quaternion's .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.");return a.applyQuaternion(this)},slerp:function(a,b){var c=this.x,d=this.y,e=this.z, +f=this.w,g=f*a.w+c*a.x+d*a.y+e*a.z;0>g?(this.w=-a.w,this.x=-a.x,this.y=-a.y,this.z=-a.z,g=-g):this.copy(a);if(1<=g)return this.w=f,this.x=c,this.y=d,this.z=e,this;var h=Math.acos(g),i=Math.sqrt(1-g*g);if(0.001>Math.abs(i))return this.w=0.5*(f+this.w),this.x=0.5*(c+this.x),this.y=0.5*(d+this.y),this.z=0.5*(e+this.z),this;g=Math.sin((1-b)*h)/i;h=Math.sin(b*h)/i;this.w=f*g+this.w*h;this.x=c*g+this.x*h;this.y=d*g+this.y*h;this.z=e*g+this.z*h;return this},equals:function(a){return a.x===this.x&&a.y=== +this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a){this.x=a[0];this.y=a[1];this.z=a[2];this.w=a[3];return this},toArray:function(){return[this.x,this.y,this.z,this.w]},clone:function(){return new THREE.Quaternion(this.x,this.y,this.z,this.w)}};THREE.Quaternion.slerp=function(a,b,c,d){return c.copy(a).slerp(b,d)};THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0}; +THREE.Vector2.prototype={constructor:THREE.Vector2,set:function(a,b){this.x=a;this.y=b;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a, +b){if(void 0!==b)return console.warn("DEPRECATED: Vector2's .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},sub:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector2's .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-= +a.y;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divideScalar:function(a){0!==a?(this.x/=a,this.y/=a):this.set(0,0);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);return this}, +negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,a=this.y-a.y;return b*b+a*a},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/ +b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a){this.x=a[0];this.y=a[1];return this},toArray:function(){return[this.x,this.y]},clone:function(){return new THREE.Vector2(this.x,this.y)}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}; +THREE.Vector3.prototype={constructor:THREE.Vector3,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+ +a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},sub:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), +this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x* +b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements,e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]); +this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z,a=a.w,h=a*b+f*d-g*c,i=a*c+g*b-e*d,j=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+i*-g-j*-f;this.y=i*a+b*-f+j*-e-h*-g;this.z=j*a+b*-g+h*-f-i*-e;return this},transformDirection:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]* +b+a[6]*c+a[10]*d;this.normalize();return this},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){0!==a?(this.x/=a,this.y/=a,this.z/=a):this.z=this.y=this.x=0;return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){var b= +this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},cross:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){this.x=a.y*b.z-a.z*b.y;this.y= +a.z*b.x-a.x*b.z;this.z=a.x*b.y-a.y*b.x;return this},angleTo:function(a){a=this.dot(a)/(this.length()*a.length());return Math.acos(THREE.Math.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y,a=this.z-a.z;return b*b+c*c+a*a},setEulerFromRotationMatrix:function(a,b){function c(a){return Math.min(Math.max(a,-1),1)}var d=a.elements,e=d[0],f=d[4],g=d[8],h=d[1],i=d[5],j=d[9],m=d[2],p=d[6],d=d[10];void 0===b||"XYZ"=== +b?(this.y=Math.asin(c(g)),0.99999>Math.abs(g)?(this.x=Math.atan2(-j,d),this.z=Math.atan2(-f,e)):(this.x=Math.atan2(p,i),this.z=0)):"YXZ"===b?(this.x=Math.asin(-c(j)),0.99999>Math.abs(j)?(this.y=Math.atan2(g,d),this.z=Math.atan2(h,i)):(this.y=Math.atan2(-m,e),this.z=0)):"ZXY"===b?(this.x=Math.asin(c(p)),0.99999>Math.abs(p)?(this.y=Math.atan2(-m,d),this.z=Math.atan2(-f,i)):(this.y=0,this.z=Math.atan2(h,e))):"ZYX"===b?(this.y=Math.asin(-c(m)),0.99999>Math.abs(m)?(this.x=Math.atan2(p,d),this.z=Math.atan2(h, +e)):(this.x=0,this.z=Math.atan2(-f,i))):"YZX"===b?(this.z=Math.asin(c(h)),0.99999>Math.abs(h)?(this.x=Math.atan2(-j,i),this.y=Math.atan2(-m,e)):(this.x=0,this.y=Math.atan2(g,d))):"XZY"===b&&(this.z=Math.asin(-c(f)),0.99999>Math.abs(f)?(this.x=Math.atan2(p,i),this.y=Math.atan2(g,e)):(this.x=Math.atan2(-j,d),this.y=0));return this},setEulerFromQuaternion:function(a,b){function c(a){return Math.min(Math.max(a,-1),1)}var d=a.x*a.x,e=a.y*a.y,f=a.z*a.z,g=a.w*a.w;void 0===b||"XYZ"===b?(this.x=Math.atan2(2* +(a.x*a.w-a.y*a.z),g-d-e+f),this.y=Math.asin(c(2*(a.x*a.z+a.y*a.w))),this.z=Math.atan2(2*(a.z*a.w-a.x*a.y),g+d-e-f)):"YXZ"===b?(this.x=Math.asin(c(2*(a.x*a.w-a.y*a.z))),this.y=Math.atan2(2*(a.x*a.z+a.y*a.w),g-d-e+f),this.z=Math.atan2(2*(a.x*a.y+a.z*a.w),g-d+e-f)):"ZXY"===b?(this.x=Math.asin(c(2*(a.x*a.w+a.y*a.z))),this.y=Math.atan2(2*(a.y*a.w-a.z*a.x),g-d-e+f),this.z=Math.atan2(2*(a.z*a.w-a.x*a.y),g-d+e-f)):"ZYX"===b?(this.x=Math.atan2(2*(a.x*a.w+a.z*a.y),g-d-e+f),this.y=Math.asin(c(2*(a.y*a.w-a.x* +a.z))),this.z=Math.atan2(2*(a.x*a.y+a.z*a.w),g+d-e-f)):"YZX"===b?(this.x=Math.atan2(2*(a.x*a.w-a.z*a.y),g-d+e-f),this.y=Math.atan2(2*(a.y*a.w-a.x*a.z),g+d-e-f),this.z=Math.asin(c(2*(a.x*a.y+a.z*a.w)))):"XZY"===b&&(this.x=Math.atan2(2*(a.x*a.w+a.y*a.z),g-d+e-f),this.y=Math.atan2(2*(a.x*a.z+a.y*a.w),g+d-e-f),this.z=Math.asin(c(2*(a.z*a.w-a.x*a.y))));return this},getPositionFromMatrix:function(a){this.x=a.elements[12];this.y=a.elements[13];this.z=a.elements[14];return this},getScaleFromMatrix:function(a){var b= +this.set(a.elements[0],a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5],a.elements[6]).length(),a=this.set(a.elements[8],a.elements[9],a.elements[10]).length();this.x=b;this.y=c;this.z=a;return this},getColumnFromMatrix:function(a,b){var c=4*a,d=b.elements;this.x=d[c];this.y=d[c+1];this.z=d[c+2];return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a){this.x=a[0];this.y=a[1];this.z=a[2];return this},toArray:function(){return[this.x, +this.y,this.z]},clone:function(){return new THREE.Vector3(this.x,this.y,this.z)}}; +THREE.extend(THREE.Vector3.prototype,{applyEuler:function(){var a=new THREE.Quaternion;return function(b,c){var d=a.setFromEuler(b,c);this.applyQuaternion(d);return this}}(),applyAxisAngle:function(){var a=new THREE.Quaternion;return function(b,c){var d=a.setFromAxisAngle(b,c);this.applyQuaternion(d);return this}}(),projectOnVector:function(){var a=new THREE.Vector3;return function(b){a.copy(b).normalize();b=this.dot(a);return this.copy(a).multiplyScalar(b)}}(),projectOnPlane:function(){var a=new THREE.Vector3; +return function(b){a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a=new THREE.Vector3;return function(b){a.copy(this).projectOnVector(b).multiplyScalar(2);return this.subVectors(a,this)}}()});THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; +THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x; +case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector4's .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this}, +addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},sub:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector4's .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this}, +applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w,a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){0!==a?(this.x/=a,this.y/=a,this.z/=a,this.w/=a):(this.z=this.y=this.x=0,this.w=1);return this},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y= +a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d,a=a.elements,e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],i=a[9];c=a[2];b=a[6];var j=a[10];if(0.01>Math.abs(d-g)&&0.01>Math.abs(f-c)&&0.01>Math.abs(i-b)){if(0.1>Math.abs(d+g)&&0.1>Math.abs(f+c)&&0.1>Math.abs(i+b)&&0.1>Math.abs(e+h+j-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;j=(j+1)/2;d=(d+g)/4;f=(f+c)/4;i=(i+b)/4;e>h&&e>j?0.01>e?(b=0,d=c=0.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):h>j?0.01>h?(b=0.707106781, +c=0,d=0.707106781):(c=Math.sqrt(h),b=d/c,d=i/c):0.01>j?(c=b=0.707106781,d=0):(d=Math.sqrt(j),b=f/d,c=i/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-i)*(b-i)+(f-c)*(f-c)+(g-d)*(g-d));0.001>Math.abs(a)&&(a=1);this.x=(b-i)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+j-1)/2);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);this.wb.w&&(this.w=b.w);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x* +this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&& +a.w===this.w},fromArray:function(a){this.x=a[0];this.y=a[1];this.z=a[2];this.w=a[3];return this},toArray:function(){return[this.x,this.y,this.z,this.w]},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)}};THREE.Line3=function(a,b){this.start=void 0!==a?a:new THREE.Vector3;this.end=void 0!==b?b:new THREE.Vector3}; +THREE.Line3.prototype={constructor:THREE.Line3,set:function(a,b){this.start.copy(a);this.end.copy(b);return this},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},center:function(a){return(a||new THREE.Vector3).addVectors(this.start,this.end).multiplyScalar(0.5)},delta:function(a){return(a||new THREE.Vector3).subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a, +b){var c=b||new THREE.Vector3;return this.delta(c).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d){a.subVectors(c,this.start);b.subVectors(this.end,this.start);var e=b.dot(b),e=b.dot(a)/e;d&&(e=THREE.Math.clamp(e,0,1));return e}}(),closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);c=c||new THREE.Vector3;return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a); +this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)},clone:function(){return(new THREE.Line3).copy(this)}};THREE.Box2=function(a,b){this.min=void 0!==a?a:new THREE.Vector2(Infinity,Infinity);this.max=void 0!==b?b:new THREE.Vector2(-Infinity,-Infinity)}; +THREE.Box2.prototype={constructor:THREE.Box2,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromPoints:function(a){if(0this.max.x&&(this.max.x=b.x),b.ythis.max.y&&(this.max.y=b.y)}else this.makeEmpty();return this},setFromCenterAndSize:function(){var a=new THREE.Vector2;return function(b,c){var d=a.copy(c).multiplyScalar(0.5); +this.min.copy(b).sub(d);this.max.copy(b).add(d);return this}}(),copy:function(a){this.min.copy(a.min);this.max.copy(a.max);return this},makeEmpty:function(){this.min.x=this.min.y=Infinity;this.max.x=this.max.y=-Infinity;return this},empty:function(){return this.max.xthis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y?!0:!1},getParameter:function(a){return new THREE.Vector2((a.x-this.min.x)/(this.max.x-this.min.x), +(a.y-this.min.y)/(this.max.y-this.min.y))},isIntersectionBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y?!1:!0},clampPoint:function(a,b){return(b||new THREE.Vector2).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new THREE.Vector2;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max); +return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)},clone:function(){return(new THREE.Box2).copy(this)}};THREE.Box3=function(a,b){this.min=void 0!==a?a:new THREE.Vector3(Infinity,Infinity,Infinity);this.max=void 0!==b?b:new THREE.Vector3(-Infinity,-Infinity,-Infinity)}; +THREE.Box3.prototype={constructor:THREE.Box3,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromPoints:function(a){if(0this.max.x&&(this.max.x=b.x),b.ythis.max.y&&(this.max.y=b.y),b.zthis.max.z&&(this.max.z=b.z)}else this.makeEmpty();return this},setFromCenterAndSize:function(){var a=new THREE.Vector3; +return function(b,c){var d=a.copy(c).multiplyScalar(0.5);this.min.copy(b).sub(d);this.max.copy(b).add(d);return this}}(),copy:function(a){this.min.copy(a.min);this.max.copy(a.max);return this},makeEmpty:function(){this.min.x=this.min.y=this.min.z=Infinity;this.max.x=this.max.y=this.max.z=-Infinity;return this},empty:function(){return this.max.xthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<= +this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z?!0:!1},getParameter:function(a){return new THREE.Vector3((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},isIntersectionBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},clampPoint:function(a,b){return(b||new THREE.Vector3).copy(a).clamp(this.min, +this.max)},distanceToPoint:function(){var a=new THREE.Vector3;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a=new THREE.Vector3;return function(b){b=b||new THREE.Sphere;b.center=this.center();b.radius=0.5*this.size(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new THREE.Vector3, +new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];return function(b){a[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b);a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x, +this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.makeEmpty();this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)},clone:function(){return(new THREE.Box3).copy(this)}};THREE.Matrix3=function(a,b,c,d,e,f,g,h,i){this.elements=new Float32Array(9);this.set(void 0!==a?a:1,b||0,c||0,d||0,void 0!==e?e:1,f||0,g||0,h||0,void 0!==i?i:1)}; +THREE.Matrix3.prototype={constructor:THREE.Matrix3,set:function(a,b,c,d,e,f,g,h,i){var j=this.elements;j[0]=a;j[3]=b;j[6]=c;j[1]=d;j[4]=e;j[7]=f;j[2]=g;j[5]=h;j[8]=i;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},copy:function(a){a=a.elements;this.set(a[0],a[3],a[6],a[1],a[4],a[7],a[2],a[5],a[8]);return this},multiplyVector3:function(a){console.warn("DEPRECATED: Matrix3's .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.");return a.applyMatrix3(this)}, +multiplyVector3Array:function(){var a=new THREE.Vector3;return function(b){for(var c=0,d=b.length;c=this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)- +this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},clampPoint:function(a,b){var c=this.center.distanceToSquared(a),d=b||new THREE.Vector3;d.copy(a);c>this.radius*this.radius&&(d.sub(this.center).normalize(),d.multiplyScalar(this.radius).add(this.center));return d},getBoundingBox:function(a){a=a||new THREE.Box3;a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a); +this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius},clone:function(){return(new THREE.Sphere).copy(this)}};THREE.Frustum=function(a,b,c,d,e,f){this.planes=[void 0!==a?a:new THREE.Plane,void 0!==b?b:new THREE.Plane,void 0!==c?c:new THREE.Plane,void 0!==d?d:new THREE.Plane,void 0!==e?e:new THREE.Plane,void 0!==f?f:new THREE.Plane]}; +THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements,a=c[0],d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],i=c[6],j=c[7],m=c[8],p=c[9],l=c[10],r=c[11],s=c[12],n=c[13],q=c[14],c=c[15];b[0].setComponents(f-a,j-g,r-m,c-s).normalize();b[1].setComponents(f+ +a,j+g,r+m,c+s).normalize();b[2].setComponents(f+d,j+h,r+p,c+n).normalize();b[3].setComponents(f-d,j-h,r-p,c-n).normalize();b[4].setComponents(f-e,j-i,r-l,c-q).normalize();b[5].setComponents(f+e,j+i,r+l,c+q).normalize();return this},intersectsObject:function(){var a=new THREE.Vector3;return function(b){var c=b.matrixWorld,d=this.planes,b=-b.geometry.boundingSphere.radius*c.getMaxScaleOnAxis();a.getPositionFromMatrix(c);for(c=0;6>c;c++)if(d[c].distanceToPoint(a)d;d++)if(b[d].distanceToPoint(c)c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0},clone:function(){return(new THREE.Frustum).copy(this)}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0}; +THREE.Plane.prototype={constructor:THREE.Plane,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d, +c);return this}}(),copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){return this.orthoPoint(a,b).sub(a).negate()},orthoPoint:function(a, +b){var c=this.distanceToPoint(a);return(b||new THREE.Vector3).copy(this.normal).multiplyScalar(c)},isIntersectionLine:function(a){var b=this.distanceToPoint(a.start),a=this.distanceToPoint(a.end);return 0>b&&0a&&0f||1c?c:a},clampBottom:function(a,b){return a=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){return(65280*Math.random()+255*Math.random())/65535},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a, +b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(0.5-Math.random())},sign:function(a){return 0>a?-1:0this.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1: +f+2;j=this.points[c[0]];m=this.points[c[1]];p=this.points[c[2]];l=this.points[c[3]];h=g*g;i=g*h;d.x=b(j.x,m.x,p.x,l.x,g,h,i);d.y=b(j.y,m.y,p.y,l.y,g,h,i);d.z=b(j.z,m.z,p.z,l.z,g,h,i);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;a=b.x+b.y}}(); +THREE.Triangle.prototype={constructor:THREE.Triangle,set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},area:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return 0.5*a.cross(b).length()}}(),midpoint:function(a){return(a|| +new THREE.Vector3).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(a){return THREE.Triangle.normal(this.a,this.b,this.c,a)},plane:function(a){return(a||new THREE.Plane).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(a,b){return THREE.Triangle.barycoordFromPoint(a,this.a,this.b,this.c,b)},containsPoint:function(a){return THREE.Triangle.containsPoint(a,this.a,this.b,this.c)},equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}, +clone:function(){return(new THREE.Triangle).copy(this)}};THREE.Vertex=function(a){console.warn("THREE.Vertex has been DEPRECATED. Use THREE.Vector3 instead.");return a};THREE.UV=function(a,b){console.warn("THREE.UV has been DEPRECATED. Use THREE.Vector2 instead.");return new THREE.Vector2(a,b)};THREE.Clock=function(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}; +THREE.Clock.prototype={constructor:THREE.Clock,start:function(){this.oldTime=this.startTime=void 0!==window.performance&&void 0!==window.performance.now?window.performance.now():Date.now();this.running=!0},stop:function(){this.getElapsedTime();this.running=!1},getElapsedTime:function(){this.getDelta();return this.elapsedTime},getDelta:function(){var a=0;this.autoStart&&!this.running&&this.start();if(this.running){var b=void 0!==window.performance&&void 0!==window.performance.now?window.performance.now(): +Date.now(),a=0.001*(b-this.oldTime);this.oldTime=b;this.elapsedTime+=a}return a}};THREE.EventDispatcher=function(){}; +THREE.EventDispatcher.prototype={constructor:THREE.EventDispatcher,addEventListener:function(a,b){void 0===this._listeners&&(this._listeners={});var c=this._listeners;void 0===c[a]&&(c[a]=[]);-1===c[a].indexOf(b)&&c[a].push(b)},hasEventListener:function(a,b){if(void 0===this._listeners)return!1;var c=this._listeners;return void 0!==c[a]&&-1!==c[a].indexOf(b)?!0:!1},removeEventListener:function(a,b){if(void 0!==this._listeners){var c=this._listeners,d=c[a].indexOf(b);-1!==d&&c[a].splice(d,1)}},dispatchEvent:function(a){if(void 0!== +this._listeners){var b=this._listeners[a.type];if(void 0!==b){a.target=this;for(var c=0,d=b.length;ch.scale.x)return l;l.push({distance:r,point:h.position,face:null,object:h})}else if(h instanceof +a.LOD)f.getPositionFromMatrix(h.matrixWorld),r=j.ray.origin.distanceTo(f),i(h.getObjectForDistance(r),j,l);else if(h instanceof a.Mesh){f.getPositionFromMatrix(h.matrixWorld);b.set(f,h.geometry.boundingSphere.radius*h.matrixWorld.getMaxScaleOnAxis());if(!j.ray.isIntersectionSphere(b))return l;var r=h.geometry,s=r.vertices,n=h.material instanceof a.MeshFaceMaterial,q=!0===n?h.material.materials:null,y=h.material.side,u,x,t,E=j.precision;g.getInverse(h.matrixWorld);c.copy(j.ray).applyMatrix4(g);for(var J= +0,F=r.faces.length;JH)){y=y.side;if(y!==a.DoubleSide&&(u=c.direction.dot(d.normal),!(y===a.FrontSide?0>u:0j.far)){e=c.at(H,e);if(z instanceof a.Face3){if(y=s[z.a],u=s[z.b],x=s[z.c],!a.Triangle.containsPoint(e,y,u,x))continue}else if(z instanceof a.Face4){if(y=s[z.a],u=s[z.b],x=s[z.c],t=s[z.d], +!a.Triangle.containsPoint(e,y,u,t)&&!a.Triangle.containsPoint(e,u,x,t))continue}else throw Error("face type not supported");l.push({distance:H,point:j.ray.at(H),face:z,faceIndex:J,object:h})}}}}}},j=function(a,b,c){for(var a=a.getDescendants(),d=0,e=a.length;de&&0>f||0>g&&0>h)return!1;0>e?c=Math.max(c,e/(e-f)):0>f&&(d=Math.min(d,e/(e-f)));0>g?c=Math.max(c,g/(g-h)):0>h&&(d=Math.min(d,g/(g-h)));if(d< +c)return!1;a.lerp(b,c);b.lerp(a,1-d);return!0}var e,f,g=[],h=0,i,j,m=[],p=0,l,r,s=[],n=0,q,y=[],u=0,x,t,E=[],J=0,F,z,H=[],K=0,G={objects:[],sprites:[],lights:[],elements:[]},L=new THREE.Vector3,B=new THREE.Vector4,V=new THREE.Box3(new THREE.Vector3(-1,-1,-1),new THREE.Vector3(1,1,1)),C=new THREE.Box3,I=Array(3),M=Array(4),R=new THREE.Matrix4,ea=new THREE.Matrix4,wa,Ma=new THREE.Matrix4,A=new THREE.Matrix3,ca=new THREE.Matrix3,ja=new THREE.Vector3,na=new THREE.Frustum,N=new THREE.Vector4,fa=new THREE.Vector4; +this.projectVector=function(a,b){b.matrixWorldInverse.getInverse(b.matrixWorld);ea.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);return a.applyProjection(ea)};this.unprojectVector=function(a,b){b.projectionMatrixInverse.getInverse(b.projectionMatrix);ea.multiplyMatrices(b.matrixWorld,b.projectionMatrixInverse);return a.applyProjection(ea)};this.pickingRay=function(a,b){a.z=-1;var c=new THREE.Vector3(a.x,a.y,1);this.unprojectVector(a,b);this.unprojectVector(c,b);c.sub(a).normalize();return new THREE.Raycaster(a, +c)};this.projectScene=function(g,h,p,Ka){var qa=!1,pa,Z,ga,W,da,la,ha,ia,Qa,kb,oa,Xa,Ra;z=t=q=r=0;G.elements.length=0;!0===g.autoUpdate&&g.updateMatrixWorld();void 0===h.parent&&h.updateMatrixWorld();R.copy(h.matrixWorldInverse.getInverse(h.matrixWorld));ea.multiplyMatrices(h.projectionMatrix,R);ca.getNormalMatrix(R);na.setFromMatrix(ea);f=0;G.objects.length=0;G.sprites.length=0;G.lights.length=0;var Aa=function(b){for(var c=0,d=b.children.length;ci.positionScreen.x||1i.positionScreen.y||1i.positionScreen.z||1(ha.positionScreen.x-W.positionScreen.x)*(da.positionScreen.y-W.positionScreen.y)-(ha.positionScreen.y-W.positionScreen.y)*(da.positionScreen.x-W.positionScreen.x),la===THREE.DoubleSide||qa===(la===THREE.FrontSide))r===n?(oa=new THREE.RenderableFace3,s.push(oa),n++,r++,l=oa):l=s[r++],l.v1.copy(W),l.v2.copy(da),l.v3.copy(ha);else continue; +else continue;else if(Z instanceof THREE.Face4)if(W=m[Z.a],da=m[Z.b],ha=m[Z.c],oa=m[Z.d],M[0]=W.positionScreen,M[1]=da.positionScreen,M[2]=ha.positionScreen,M[3]=oa.positionScreen,!0===W.visible||!0===da.visible||!0===ha.visible||!0===oa.visible||V.isIntersectionBox(C.setFromPoints(M)))if(qa=0>(oa.positionScreen.x-W.positionScreen.x)*(da.positionScreen.y-W.positionScreen.y)-(oa.positionScreen.y-W.positionScreen.y)*(da.positionScreen.x-W.positionScreen.x)||0>(da.positionScreen.x-ha.positionScreen.x)* +(oa.positionScreen.y-ha.positionScreen.y)-(da.positionScreen.y-ha.positionScreen.y)*(oa.positionScreen.x-ha.positionScreen.x),la===THREE.DoubleSide||qa===(la===THREE.FrontSide)){if(q===u){var sb=new THREE.RenderableFace4;y.push(sb);u++;q++;l=sb}else l=y[q++];l.v1.copy(W);l.v2.copy(da);l.v3.copy(ha);l.v4.copy(oa)}else continue;else continue;l.normalModel.copy(Z.normal);!1===qa&&(la===THREE.BackSide||la===THREE.DoubleSide)&&l.normalModel.negate();l.normalModel.applyMatrix3(A).normalize();l.normalModelView.copy(l.normalModel).applyMatrix3(ca); +l.centroidModel.copy(Z.centroid).applyMatrix4(wa);ha=Z.vertexNormals;W=0;for(da=ha.length;WB.z&&(z===K?(qa=new THREE.RenderableParticle,H.push(qa),K++, +z++,F=qa):F=H[z++],F.object=ia,F.x=B.x/B.w,F.y=B.y/B.w,F.z=B.z,F.rotation=ia.rotation.z,F.scale.x=ia.scale.x*Math.abs(F.x-(B.x+h.projectionMatrix.elements[0])/(B.w+h.projectionMatrix.elements[12])),F.scale.y=ia.scale.y*Math.abs(F.y-(B.y+h.projectionMatrix.elements[5])/(B.w+h.projectionMatrix.elements[13])),F.material=ia.material,G.elements.push(F)));!0===Ka&&G.elements.sort(c);return G}};THREE.Face3=function(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d instanceof THREE.Vector3?d:new THREE.Vector3;this.vertexNormals=d instanceof Array?d:[];this.color=e instanceof THREE.Color?e:new THREE.Color;this.vertexColors=e instanceof Array?e:[];this.vertexTangents=[];this.materialIndex=void 0!==f?f:0;this.centroid=new THREE.Vector3}; THREE.Face3.prototype={constructor:THREE.Face3,clone:function(){var a=new THREE.Face3(this.a,this.b,this.c);a.normal.copy(this.normal);a.color.copy(this.color);a.centroid.copy(this.centroid);a.materialIndex=this.materialIndex;var b,c;b=0;for(c=this.vertexNormals.length;be?-1:1,f.vertexTangents[d]=new THREE.Vector4(B.x,B.y,B.z,e)}this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cc.x&&(c.x=a.x),a.yc.y&&(c.y=a.y),a.zc.z&&(c.z=a.z)}else this.boundingBox.min.set(0,0,0),this.boundingBox.max.set(0,0,0)},computeBoundingSphere:function(){var a=0;null===this.boundingSphere&&(this.boundingSphere={radius:0});for(var b= -0,c=this.vertices.length;ba&&(a=d)}this.boundingSphere.radius=Math.sqrt(a)},mergeVertices:function(){var a={},b=[],c=[],d,e=Math.pow(10,4),f,g,h,i;f=0;for(g=this.vertices.length;fb.max.x&&(b.max.x=c),db.max.y&&(b.max.y=d),eb.max.z&&(b.max.z=e);if(void 0===a||0===a.length)this.boundingBox.min.set(0,0,0),this.boundingBox.max.set(0,0,0)},computeBoundingSphere:function(){this.boundingSphere||(this.boundingSphere={radius:0}); -var a=this.attributes.position.array;if(a){for(var b,c=0,d,e,f=0,g=a.length;fc&&(c=b);this.boundingSphere.radius=Math.sqrt(c)}},computeVertexNormals:function(){if(this.attributes.position&&this.attributes.index){var a,b,c,d;a=this.attributes.position.array.length;if(void 0===this.attributes.normal)this.attributes.normal={itemSize:3,array:new Float32Array(a),numItems:a};else{a=0;for(b=this.attributes.normal.array.length;aZ?-1:1;h[4*a]=O.x;h[4*a+1]=O.y;h[4*a+2]=O.z;h[4*a+3]=J}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var b=this.attributes.index.array,c=this.attributes.position.array,d=this.attributes.normal.array,e=this.attributes.uv.array,f=c.length/3;if(void 0===this.attributes.tangent){var g= -4*f;this.attributes.tangent={itemSize:4,array:new Float32Array(g),numItems:g}}for(var h=this.attributes.tangent.array,i=[],j=[],g=0;gthis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1: -f+2;j=this.points[c[0]];l=this.points[c[1]];m=this.points[c[2]];n=this.points[c[3]];h=g*g;i=g*h;d.x=b(j.x,l.x,m.x,n.x,g,h,i);d.y=b(j.y,l.y,m.y,n.y,g,h,i);d.z=b(j.z,l.z,m.z,n.z,g,h,i);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;ae?-1:1,f.vertexTangents[d]=new THREE.Vector4(B.x,B.y,B.z,e)}this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;ci;i++)if(h[i]==h[(i+1)%3]){e.push(f);break}}else if(a instanceof THREE.Face4){a.a=c[a.a];a.b=c[a.b];a.c=c[a.c];a.d=c[a.d];h=[a.a,a.b,a.c,a.d];d=-1;for(i=0;4>i;i++)h[i]==h[(i+1)%4]&&(0<=d&&e.push(f),d=i);if(0<= +d){h.splice(d,1);var m=new THREE.Face3(h[0],h[1],h[2],a.normal,a.color,a.materialIndex);h=0;for(i=this.faceVertexUvs.length;hb.max.x&&(b.max.x=c),db.max.y&&(b.max.y=d),eb.max.z&&(b.max.z=e)}if(void 0===a||0===a.length)this.boundingBox.min.set(0,0,0),this.boundingBox.max.set(0,0,0)},computeBoundingSphere:function(){null===this.boundingSphere&&(this.boundingSphere=new THREE.Sphere);var a=this.attributes.position.array;if(a){for(var b,c=0,d,e,f=0,g=a.length;fc&&(c=b);this.boundingSphere.radius=Math.sqrt(c)}},computeVertexNormals:function(){if(this.attributes.position){var a, +b,c,d;a=this.attributes.position.array.length;if(void 0===this.attributes.normal)this.attributes.normal={itemSize:3,array:new Float32Array(a),numItems:a};else{a=0;for(b=this.attributes.normal.array.length;aja?-1:1;h[4*a]=R.x;h[4*a+1]=R.y;h[4*a+2]=R.z;h[4*a+3]=A}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var b=this.attributes.index.array,c=this.attributes.position.array, +d=this.attributes.normal.array,e=this.attributes.uv.array,f=c.length/3;if(void 0===this.attributes.tangent){var g=4*f;this.attributes.tangent={itemSize:4,array:new Float32Array(g),numItems:g}}for(var h=this.attributes.tangent.array,i=[],j=[],g=0;ga.length?".":a.join("/"))+"/"},initMaterials:function(a,b){for(var c=[],d=0;da.opacity)i.transparent=a.transparent;void 0!==a.depthTest&&(i.depthTest=a.depthTest);void 0!==a.depthWrite&&(i.depthWrite=a.depthWrite);void 0!==a.visible&&(i.visible=a.visible);void 0!==a.flipSided&&(i.side=THREE.BackSide); void 0!==a.doubleSided&&(i.side=THREE.DoubleSide);void 0!==a.wireframe&&(i.wireframe=a.wireframe);void 0!==a.vertexColors&&("face"===a.vertexColors?i.vertexColors=THREE.FaceColors:a.vertexColors&&(i.vertexColors=THREE.VertexColors));a.colorDiffuse?i.color=f(a.colorDiffuse):a.DbgColor&&(i.color=a.DbgColor);a.colorSpecular&&(i.specular=f(a.colorSpecular));a.colorAmbient&&(i.ambient=f(a.colorAmbient));a.transparency&&(i.opacity=a.transparency);a.specularCoef&&(i.shininess=a.specularCoef);a.mapDiffuse&& b&&e(i,"map",a.mapDiffuse,a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&e(i,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&e(i,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&e(i,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&e(i,"specularMap",a.mapSpecular,a.mapSpecularRepeat, -a.mapSpecularOffset,a.mapSpecularWrap,a.mapSpecularAnisotropy);a.mapBumpScale&&(i.bumpScale=a.mapBumpScale);a.mapNormal?(h=THREE.ShaderUtils.lib.normal,j=THREE.UniformsUtils.clone(h.uniforms),j.tNormal.value=i.normalMap,a.mapNormalFactor&&j.uNormalScale.value.set(a.mapNormalFactor,a.mapNormalFactor),i.map&&(j.tDiffuse.value=i.map,j.enableDiffuse.value=!0),i.specularMap&&(j.tSpecular.value=i.specularMap,j.enableSpecular.value=!0),i.lightMap&&(j.tAO.value=i.lightMap,j.enableAO.value=!0),j.uDiffuseColor.value.setHex(i.color), -j.uSpecularColor.value.setHex(i.specular),j.uAmbientColor.value.setHex(i.ambient),j.uShininess.value=i.shininess,void 0!==i.opacity&&(j.uOpacity.value=i.opacity),i=new THREE.ShaderMaterial({fragmentShader:h.fragmentShader,vertexShader:h.vertexShader,uniforms:j,lights:!0,fog:!0})):i=new THREE[h](i);void 0!==a.DbgName&&(i.name=a.DbgName);return i}};THREE.BinaryLoader=function(a){THREE.Loader.call(this,a)};THREE.BinaryLoader.prototype=Object.create(THREE.Loader.prototype); -THREE.BinaryLoader.prototype.load=function(a,b,c,d){var c=c&&"string"===typeof c?c:this.extractUrlBase(a),d=d&&"string"===typeof d?d:this.extractUrlBase(a),e=this.showProgress?THREE.Loader.prototype.updateProgress:null;this.onLoadStart();this.loadAjaxJSON(this,a,b,c,d,e)}; -THREE.BinaryLoader.prototype.loadAjaxJSON=function(a,b,c,d,e,f){var g=new XMLHttpRequest;g.onreadystatechange=function(){if(4==g.readyState)if(200==g.status||0==g.status){var h=JSON.parse(g.responseText);a.loadAjaxBuffers(h,c,e,d,f)}else console.error("THREE.BinaryLoader: Couldn't load ["+b+"] ["+g.status+"]")};g.open("GET",b,!0);g.send(null)}; -THREE.BinaryLoader.prototype.loadAjaxBuffers=function(a,b,c,d,e){var f=new XMLHttpRequest,g=c+"/"+a.buffers,h=0;f.onreadystatechange=function(){if(4==f.readyState)if(200==f.status||0==f.status){var c=f.response;void 0===c&&(c=(new Uint8Array(f.responseBody)).buffer);THREE.BinaryLoader.prototype.createBinModel(c,b,d,a.materials)}else console.error("THREE.BinaryLoader: Couldn't load ["+g+"] ["+f.status+"]");else 3==f.readyState?e&&(0==h&&(h=f.getResponseHeader("Content-Length")),e({total:h,loaded:f.responseText.length})): -2==f.readyState&&(h=f.getResponseHeader("Content-Length"))};f.open("GET",g,!0);f.responseType="arraybuffer";f.send(null)}; -THREE.BinaryLoader.prototype.createBinModel=function(a,b,c,d){var e=function(){var b,c,d,e,j,l,m,n,p,o,s,t,r,z,w,q;function E(a){return a%4?4-a%4:0}function A(a,b){return(new Uint8Array(a,b,1))[0]}function v(a,b){return(new Uint32Array(a,b,1))[0]}function u(b,c){var d,e,f,g,h,i,j,l=new Uint32Array(a,c,3*b);for(d=0;dr;r++)o+=String.fromCharCode(z[R+r]);b=A(q,R+12);A(q,R+13);A(q,R+14);A(q,R+15);c=A(q,R+16);d=A(q,R+17);e=A(q,R+18);j=A(q,R+19);l=v(q,R+20);m=v(q,R+20+4);n=v(q,R+20+8);p=v(q,R+20+12);o=v(q,R+20+16);s=v(q,R+20+20);t=v(q,R+20+24);r=v(q,R+20+28);z=v(q,R+20+32);w=v(q,R+20+36);q=v(q,R+20+40);H+=b;R=3*c+j;ga=4*c+j;O=p*R;b=o*(R+3*d);c= -s*(R+3*e);j=t*(R+3*d+3*e);R=r*ga;d=z*(ga+4*d);e=w*(ga+4*e);ga=H;var H=new Float32Array(a,H,3*l),M,J,Q,Z;for(M=0;Mr.parameters.opacity&&(r.parameters.transparent=!0);r.parameters.normalMap?(s=THREE.ShaderUtils.lib.normal,Z=THREE.UniformsUtils.clone(s.uniforms),n=r.parameters.color,B=r.parameters.specular,L=r.parameters.ambient,o=r.parameters.shininess,Z.tNormal.value=M.textures[r.parameters.normalMap],r.parameters.normalScale&&Z.uNormalScale.value.set(r.parameters.normalScale[0], -r.parameters.normalScale[1]),r.parameters.map&&(Z.tDiffuse.value=r.parameters.map,Z.enableDiffuse.value=!0),r.parameters.envMap&&(Z.tCube.value=r.parameters.envMap,Z.enableReflection.value=!0,Z.uReflectivity.value=r.parameters.reflectivity),r.parameters.lightMap&&(Z.tAO.value=r.parameters.lightMap,Z.enableAO.value=!0),r.parameters.specularMap&&(Z.tSpecular.value=M.textures[r.parameters.specularMap],Z.enableSpecular.value=!0),r.parameters.displacementMap&&(Z.tDisplacement.value=M.textures[r.parameters.displacementMap], -Z.enableDisplacement.value=!0,Z.uDisplacementBias.value=r.parameters.displacementBias,Z.uDisplacementScale.value=r.parameters.displacementScale),Z.uDiffuseColor.value.setHex(n),Z.uSpecularColor.value.setHex(B),Z.uAmbientColor.value.setHex(L),Z.uShininess.value=o,r.parameters.opacity&&(Z.uOpacity.value=r.parameters.opacity),C=new THREE.ShaderMaterial({fragmentShader:s.fragmentShader,vertexShader:s.vertexShader,uniforms:Z,lights:!0,fog:!0})):C=new THREE[r.type](r.parameters);M.materials[p]=C}for(p in Q.materials)if(r= -Q.materials[p],r.parameters.materials){u=[];for(B=0;BC.parameters.opacity&&(C.parameters.transparent=!0);C.parameters.normalMap?(G=THREE.ShaderLib.normalmap,B=THREE.UniformsUtils.clone(G.uniforms),q=C.parameters.color,V=C.parameters.specular,n=C.parameters.ambient,L=C.parameters.shininess,B.tNormal.value=z.textures[C.parameters.normalMap],C.parameters.normalScale&&B.uNormalScale.value.set(C.parameters.normalScale[0], +C.parameters.normalScale[1]),C.parameters.map&&(B.tDiffuse.value=C.parameters.map,B.enableDiffuse.value=!0),C.parameters.envMap&&(B.tCube.value=C.parameters.envMap,B.enableReflection.value=!0,B.uReflectivity.value=C.parameters.reflectivity),C.parameters.lightMap&&(B.tAO.value=C.parameters.lightMap,B.enableAO.value=!0),C.parameters.specularMap&&(B.tSpecular.value=z.textures[C.parameters.specularMap],B.enableSpecular.value=!0),C.parameters.displacementMap&&(B.tDisplacement.value=z.textures[C.parameters.displacementMap], +B.enableDisplacement.value=!0,B.uDisplacementBias.value=C.parameters.displacementBias,B.uDisplacementScale.value=C.parameters.displacementScale),B.uDiffuseColor.value.setHex(q),B.uSpecularColor.value.setHex(V),B.uAmbientColor.value.setHex(n),B.uShininess.value=L,C.parameters.opacity&&(B.uOpacity.value=C.parameters.opacity),r=new THREE.ShaderMaterial({fragmentShader:G.fragmentShader,vertexShader:G.vertexShader,uniforms:B,lights:!0,fog:!0})):r=new THREE[C.type](C.parameters);r.name=I;z.materials[I]= +r}for(I in K.materials)if(C=K.materials[I],C.parameters.materials){M=[];for(q=0;qh.end&&(h.end=e);b||(b=g)}}a.firstAnimation=b}; THREE.MorphAnimMesh.prototype.setAnimationLabel=function(a,b,c){this.geometry.animations||(this.geometry.animations={});this.geometry.animations[a]={start:b,end:c}};THREE.MorphAnimMesh.prototype.playAnimation=function(a,b){var c=this.geometry.animations[a];c?(this.setFrameRange(c.start,c.end),this.duration=1E3*((c.end-c.start)/b),this.time=0):console.warn("animation["+a+"] undefined")}; -THREE.MorphAnimMesh.prototype.updateAnimation=function(a){var b=this.duration/this.length;this.time+=this.direction*a;if(this.mirroredLoop){if(this.time>this.duration||0>this.time)if(this.direction*=-1,this.time>this.duration&&(this.time=this.duration,this.directionBackwards=!0),0>this.time)this.time=0,this.directionBackwards=!1}else this.time%=this.duration,0>this.time&&(this.time+=this.duration);a=this.startKeyframe+THREE.Math.clamp(Math.floor(this.time/b),0,this.length-1);a!==this.currentKeyframe&& +THREE.MorphAnimMesh.prototype.updateAnimation=function(a){var b=this.duration/this.length;this.time+=this.direction*a;if(this.mirroredLoop){if(this.time>this.duration||0>this.time)this.direction*=-1,this.time>this.duration&&(this.time=this.duration,this.directionBackwards=!0),0>this.time&&(this.time=0,this.directionBackwards=!1)}else this.time%=this.duration,0>this.time&&(this.time+=this.duration);a=this.startKeyframe+THREE.Math.clamp(Math.floor(this.time/b),0,this.length-1);a!==this.currentKeyframe&& (this.morphTargetInfluences[this.lastKeyframe]=0,this.morphTargetInfluences[this.currentKeyframe]=1,this.morphTargetInfluences[a]=0,this.lastKeyframe=this.currentKeyframe,this.currentKeyframe=a);b=this.time%b/b;this.directionBackwards&&(b=1-b);this.morphTargetInfluences[this.currentKeyframe]=b;this.morphTargetInfluences[this.lastKeyframe]=1-b}; -THREE.MorphAnimMesh.prototype.clone=function(a){void 0===a&&(a=new THREE.MorphAnimMesh(this.geometry,this.material));a.duration=this.duration;a.mirroredLoop=this.mirroredLoop;a.time=this.time;a.lastKeyframe=this.lastKeyframe;a.currentKeyframe=this.currentKeyframe;a.direction=this.direction;a.directionBackwards=this.directionBackwards;THREE.Mesh.prototype.clone.call(this,a);return a};THREE.Ribbon=function(a,b){THREE.Object3D.call(this);this.geometry=a;this.material=b};THREE.Ribbon.prototype=Object.create(THREE.Object3D.prototype); -THREE.Ribbon.prototype.clone=function(a){void 0===a&&(a=new THREE.Ribbon(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a);return a};THREE.LOD=function(){THREE.Object3D.call(this);this.LODs=[]};THREE.LOD.prototype=Object.create(THREE.Object3D.prototype);THREE.LOD.prototype.addLevel=function(a,b){void 0===b&&(b=0);for(var b=Math.abs(b),c=0;c=this.LODs[b].visibleAtDistance)this.LODs[b-1].object3D.visible=!1,this.LODs[b].object3D.visible=!0;else break;for(;b=this.objects[d].distance)this.objects[d-1].object.visible=!1,this.objects[d].object.visible=!0;else break;for(;dr&&s.clearRect(Math.floor(Sa.getX()),Math.floor(Sa.getY()),Math.floor(Sa.getWidth()), -Math.floor(Sa.getHeight())),0=k||(k*=f.intensity,c.r+=g.r*k, -c.g+=g.g*k,c.b+=g.b*k)}else f instanceof THREE.PointLight&&(h=f.matrixWorld.getPosition(),k=b.dot(va.sub(h,a).normalize()),0>=k||(k*=0==f.distance?1:1-Math.min(a.distanceTo(h)/f.distance,1),0!=k&&(k*=f.intensity,c.r+=g.r*k,c.g+=g.g*k,c.b+=g.b*k)))}}function m(a,d,e,g,h,k,i,j){f.info.render.vertices+=3;f.info.render.faces++;b(j.opacity);c(j.blending);H=a.positionScreen.x;I=a.positionScreen.y;N=d.positionScreen.x;O=d.positionScreen.y;R=e.positionScreen.x;ga=e.positionScreen.y;r(H,I,N,O,R,ga);(j instanceof -THREE.MeshLambertMaterial||j instanceof THREE.MeshPhongMaterial)&&null===j.map&&null===j.map?(aa.copy(j.color),ia.copy(j.emissive),j.vertexColors===THREE.FaceColors&&(aa.r*=i.color.r,aa.g*=i.color.g,aa.b*=i.color.b),!0===kb)?!1===j.wireframe&&j.shading==THREE.SmoothShading&&3==i.vertexNormalsLength?(fa.r=ca.r=Y.r=Oa.r,fa.g=ca.g=Y.g=Oa.g,fa.b=ca.b=Y.b=Oa.b,n(i.v1.positionWorld,i.vertexNormalsWorld[0],fa),n(i.v2.positionWorld,i.vertexNormalsWorld[1],ca),n(i.v3.positionWorld,i.vertexNormalsWorld[2], -Y),fa.r=fa.r*aa.r+ia.r,fa.g=fa.g*aa.g+ia.g,fa.b=fa.b*aa.b+ia.b,ca.r=ca.r*aa.r+ia.r,ca.g=ca.g*aa.g+ia.g,ca.b=ca.b*aa.b+ia.b,Y.r=Y.r*aa.r+ia.r,Y.g=Y.g*aa.g+ia.g,Y.b=Y.b*aa.b+ia.b,ba.r=0.5*(ca.r+Y.r),ba.g=0.5*(ca.g+Y.g),ba.b=0.5*(ca.b+Y.b),sa=yc(fa,ca,Y,ba),na(H,I,N,O,R,ga,0,0,1,0,0,1,sa)):(X.r=Oa.r,X.g=Oa.g,X.b=Oa.b,n(i.centroidWorld,i.normalWorld,X),X.r=X.r*aa.r+ia.r,X.g=X.g*aa.g+ia.g,X.b=X.b*aa.b+ia.b,!0===j.wireframe?t(X,j.wireframeLinewidth,j.wireframeLinecap,j.wireframeLinejoin):w(X)):!0===j.wireframe? -t(j.color,j.wireframeLinewidth,j.wireframeLinecap,j.wireframeLinejoin):w(j.color):j instanceof THREE.MeshBasicMaterial||j instanceof THREE.MeshLambertMaterial||j instanceof THREE.MeshPhongMaterial?null!==j.map?j.map.mapping instanceof THREE.UVMapping&&(Ea=i.uvs[0],z(H,I,N,O,R,ga,Ea[g].u,Ea[g].v,Ea[h].u,Ea[h].v,Ea[k].u,Ea[k].v,j.map)):null!==j.envMap?j.envMap.mapping instanceof THREE.SphericalReflectionMapping&&(a=l.matrixWorldInverse,va.copy(i.vertexNormalsWorld[g]),rb=0.5*(va.x*a.elements[0]+va.y* -a.elements[4]+va.z*a.elements[8])+0.5,ib=0.5*(va.x*a.elements[1]+va.y*a.elements[5]+va.z*a.elements[9])+0.5,va.copy(i.vertexNormalsWorld[h]),ob=0.5*(va.x*a.elements[0]+va.y*a.elements[4]+va.z*a.elements[8])+0.5,jb=0.5*(va.x*a.elements[1]+va.y*a.elements[5]+va.z*a.elements[9])+0.5,va.copy(i.vertexNormalsWorld[k]),Bb=0.5*(va.x*a.elements[0]+va.y*a.elements[4]+va.z*a.elements[8])+0.5,Cb=0.5*(va.x*a.elements[1]+va.y*a.elements[5]+va.z*a.elements[9])+0.5,z(H,I,N,O,R,ga,rb,ib,ob,jb,Bb,Cb,j.envMap)):(X.copy(j.color), -j.vertexColors===THREE.FaceColors&&(X.r*=i.color.r,X.g*=i.color.g,X.b*=i.color.b),!0===j.wireframe?t(X,j.wireframeLinewidth,j.wireframeLinecap,j.wireframeLinejoin):w(X)):j instanceof THREE.MeshDepthMaterial?(Ja=l.near,ma=l.far,fa.r=fa.g=fa.b=1-Db(a.positionScreen.z,Ja,ma),ca.r=ca.g=ca.b=1-Db(d.positionScreen.z,Ja,ma),Y.r=Y.g=Y.b=1-Db(e.positionScreen.z,Ja,ma),ba.r=0.5*(ca.r+Y.r),ba.g=0.5*(ca.g+Y.g),ba.b=0.5*(ca.b+Y.b),sa=yc(fa,ca,Y,ba),na(H,I,N,O,R,ga,0,0,1,0,0,1,sa)):j instanceof THREE.MeshNormalMaterial&& -(X.r=ic(i.normalWorld.x),X.g=ic(i.normalWorld.y),X.b=ic(i.normalWorld.z),!0===j.wireframe?t(X,j.wireframeLinewidth,j.wireframeLinecap,j.wireframeLinejoin):w(X))}function r(a,b,c,d,e,f){s.beginPath();s.moveTo(a,b);s.lineTo(c,d);s.lineTo(e,f);s.closePath()}function q(a,b,c,d,e,f,g,h){s.beginPath();s.moveTo(a,b);s.lineTo(c,d);s.lineTo(e,f);s.lineTo(g,h);s.closePath()}function t(a,b,c,e){A!==b&&(A=s.lineWidth=b);v!==c&&(v=s.lineCap=c);u!==e&&(u=s.lineJoin=e);d(a.getContextStyle());s.stroke();Ka.inflate(2* -b)}function w(a){e(a.getContextStyle());s.fill()}function z(a,b,c,d,f,g,h,k,i,j,l,n,na){if(!(na instanceof THREE.DataTexture||void 0===na.image||0==na.image.width)){if(!0===na.needsUpdate){var m=na.wrapS==THREE.RepeatWrapping,o=na.wrapT==THREE.RepeatWrapping;Aa[na.id]=s.createPattern(na.image,!0===m&&!0===o?"repeat":!0===m&&!1===o?"repeat-x":!1===m&&!0===o?"repeat-y":"no-repeat");na.needsUpdate=!1}void 0===Aa[na.id]?e("rgba(0,0,0,1)"):e(Aa[na.id]);var m=na.offset.x/na.repeat.x,o=na.offset.y/na.repeat.y, -Db=na.image.width*na.repeat.x,p=na.image.height*na.repeat.y,h=(h+m)*Db,k=(1-k+o)*p,c=c-a,d=d-b,f=f-a,g=g-b,i=(i+m)*Db-h,j=(1-j+o)*p-k,l=(l+m)*Db-h,n=(1-n+o)*p-k,m=i*n-l*j;0===m?(void 0===Na[na.id]&&(b=document.createElement("canvas"),b.width=na.image.width,b.height=na.image.height,b=b.getContext("2d"),b.drawImage(na.image,0,0),Na[na.id]=b.getImageData(0,0,na.image.width,na.image.height).data),b=Na[na.id],h=4*(Math.floor(h)+Math.floor(k)*na.image.width),X.setRGB(b[h]/255,b[h+1]/255,b[h+2]/255),w(X)): -(m=1/m,na=(n*c-j*f)*m,j=(n*d-j*g)*m,c=(i*f-l*c)*m,d=(i*g-l*d)*m,a=a-na*h-c*k,h=b-j*h-d*k,s.save(),s.transform(na,j,c,d,a,h),s.fill(),s.restore())}}function na(a,b,c,d,e,f,g,h,k,i,j,l,na){var n,m;n=na.width-1;m=na.height-1;g*=n;h*=m;c-=a;d-=b;e-=a;f-=b;k=k*n-g;i=i*m-h;j=j*n-g;l=l*m-h;m=1/(k*l-j*i);n=(l*c-i*e)*m;i=(l*d-i*f)*m;c=(k*e-j*c)*m;d=(k*f-j*d)*m;a=a-n*g-c*h;b=b-i*g-d*h;s.save();s.transform(n,i,c,d,a,b);s.clip();s.drawImage(na,0,0);s.restore()}function yc(a,b,c,d){xa[0]=255*a.r|0;xa[1]=255*a.g| -0;xa[2]=255*a.b|0;xa[4]=255*b.r|0;xa[5]=255*b.g|0;xa[6]=255*b.b|0;xa[8]=255*c.r|0;xa[9]=255*c.g|0;xa[10]=255*c.b|0;xa[12]=255*d.r|0;xa[13]=255*d.g|0;xa[14]=255*d.b|0;pb.putImageData(bb,0,0);sb.drawImage(eb,0,0);return mb}function Db(a,b,c){a=(a-b)/(c-b);return a*a*(3-2*a)}function ic(a){a=0.5*(a+1);return 0>a?0:1>1,Rc=ka.height>>1,tb=cb.scale.x*p,ub=cb.scale.y*o,E=tb*jc,Ab=ub*Rc,Ka.set(la.x-E,la.y-Ab,la.x+E,la.y+Ab),!1!==Wa.intersects(Ka)&&(s.save(),s.translate(la.x,la.y),s.rotate(-cb.rotation),s.scale(tb,-ub),s.translate(-jc,-Rc),s.drawImage(ka,0,0),s.restore())):da instanceof THREE.ParticleCanvasMaterial&&(E=cb.scale.x*p,Ab=cb.scale.y*o,Ka.set(la.x- -E,la.y-Ab,la.x+E,la.y+Ab),!1!==Wa.intersects(Ka)&&(d(da.color.getContextStyle()),e(da.color.getContextStyle()),s.save(),s.translate(la.x,la.y),s.rotate(-cb.rotation),s.scale(E,Ab),da.program(s),s.restore()))}else if(ka instanceof THREE.RenderableLine){if(D=ka.v1,C=ka.v2,D.positionScreen.x*=p,D.positionScreen.y*=o,C.positionScreen.x*=p,C.positionScreen.y*=o,Ka.addPoint(D.positionScreen.x,D.positionScreen.y),Ka.addPoint(C.positionScreen.x,C.positionScreen.y),!0===Wa.intersects(Ka)&&(la=D,cb=C,b(da.opacity), -c(da.blending),s.beginPath(),s.moveTo(la.positionScreen.x,la.positionScreen.y),s.lineTo(cb.positionScreen.x,cb.positionScreen.y),da instanceof THREE.LineBasicMaterial))la=da.linewidth,A!==la&&(A=s.lineWidth=la),la=da.linecap,v!==la&&(v=s.lineCap=la),la=da.linejoin,u!==la&&(u=s.lineJoin=la),d(da.color.getContextStyle()),s.stroke(),Ka.inflate(2*da.linewidth)}else if(ka instanceof THREE.RenderableFace3)D=ka.v1,C=ka.v2,G=ka.v3,D.positionScreen.x*=p,D.positionScreen.y*=o,C.positionScreen.x*=p,C.positionScreen.y*= -o,G.positionScreen.x*=p,G.positionScreen.y*=o,!0===da.overdraw&&(Zb(D.positionScreen,C.positionScreen),Zb(C.positionScreen,G.positionScreen),Zb(G.positionScreen,D.positionScreen)),Ka.add3Points(D.positionScreen.x,D.positionScreen.y,C.positionScreen.x,C.positionScreen.y,G.positionScreen.x,G.positionScreen.y),!0===Wa.intersects(Ka)&&m(D,C,G,0,1,2,ka,da,a);else if(ka instanceof THREE.RenderableFace4&&(D=ka.v1,C=ka.v2,G=ka.v3,P=ka.v4,D.positionScreen.x*=p,D.positionScreen.y*=o,C.positionScreen.x*=p,C.positionScreen.y*= -o,G.positionScreen.x*=p,G.positionScreen.y*=o,P.positionScreen.x*=p,P.positionScreen.y*=o,B.positionScreen.copy(C.positionScreen),K.positionScreen.copy(P.positionScreen),!0===da.overdraw&&(Zb(D.positionScreen,C.positionScreen),Zb(C.positionScreen,P.positionScreen),Zb(P.positionScreen,D.positionScreen),Zb(G.positionScreen,B.positionScreen),Zb(G.positionScreen,K.positionScreen)),Ka.addPoint(D.positionScreen.x,D.positionScreen.y),Ka.addPoint(C.positionScreen.x,C.positionScreen.y),Ka.addPoint(G.positionScreen.x, -G.positionScreen.y),Ka.addPoint(P.positionScreen.x,P.positionScreen.y),!0===Wa.intersects(Ka)))(la=D,cb=C,E=G,Ab=P,tb=B,ub=K,jc=a,f.info.render.vertices+=4,f.info.render.faces++,b(da.opacity),c(da.blending),void 0!==da.map&&null!==da.map||void 0!==da.envMap&&null!==da.envMap)?(m(la,cb,Ab,0,1,3,ka,da,jc),m(tb,E,ub,1,2,3,ka,da,jc)):(H=la.positionScreen.x,I=la.positionScreen.y,N=cb.positionScreen.x,O=cb.positionScreen.y,R=E.positionScreen.x,ga=E.positionScreen.y,M=Ab.positionScreen.x,J=Ab.positionScreen.y, -Q=tb.positionScreen.x,Z=tb.positionScreen.y,L=ub.positionScreen.x,oa=ub.positionScreen.y,da instanceof THREE.MeshLambertMaterial||da instanceof THREE.MeshPhongMaterial)?(aa.copy(da.color),ia.copy(da.emissive),da.vertexColors===THREE.FaceColors&&(aa.r*=ka.color.r,aa.g*=ka.color.g,aa.b*=ka.color.b),!0===kb)?!1===da.wireframe&&da.shading==THREE.SmoothShading&&4==ka.vertexNormalsLength?(fa.r=ca.r=Y.r=ba.r=Oa.r,fa.g=ca.g=Y.g=ba.g=Oa.g,fa.b=ca.b=Y.b=ba.b=Oa.b,n(ka.v1.positionWorld,ka.vertexNormalsWorld[0], -fa),n(ka.v2.positionWorld,ka.vertexNormalsWorld[1],ca),n(ka.v4.positionWorld,ka.vertexNormalsWorld[3],Y),n(ka.v3.positionWorld,ka.vertexNormalsWorld[2],ba),fa.r=fa.r*aa.r+ia.r,fa.g=fa.g*aa.g+ia.g,fa.b=fa.b*aa.b+ia.b,ca.r=ca.r*aa.r+ia.r,ca.g=ca.g*aa.g+ia.g,ca.b=ca.b*aa.b+ia.b,Y.r=Y.r*aa.r+ia.r,Y.g=Y.g*aa.g+ia.g,Y.b=Y.b*aa.b+ia.b,ba.r=ba.r*aa.r+ia.r,ba.g=ba.g*aa.g+ia.g,ba.b=ba.b*aa.b+ia.b,sa=yc(fa,ca,Y,ba),r(H,I,N,O,M,J),na(H,I,N,O,M,J,0,0,1,0,0,1,sa),r(Q,Z,R,ga,L,oa),na(Q,Z,R,ga,L,oa,1,0,1,1,0,1,sa)): -(X.r=Oa.r,X.g=Oa.g,X.b=Oa.b,n(ka.centroidWorld,ka.normalWorld,X),X.r=X.r*aa.r+ia.r,X.g=X.g*aa.g+ia.g,X.b=X.b*aa.b+ia.b,q(H,I,N,O,R,ga,M,J),!0===da.wireframe?t(X,da.wireframeLinewidth,da.wireframeLinecap,da.wireframeLinejoin):w(X)):(X.r=aa.r+ia.r,X.g=aa.g+ia.g,X.b=aa.b+ia.b,q(H,I,N,O,R,ga,M,J),!0===da.wireframe?t(X,da.wireframeLinewidth,da.wireframeLinecap,da.wireframeLinejoin):w(X)):da instanceof THREE.MeshBasicMaterial?(X.copy(da.color),da.vertexColors===THREE.FaceColors&&(X.r*=ka.color.r,X.g*=ka.color.g, -X.b*=ka.color.b),q(H,I,N,O,R,ga,M,J),!0===da.wireframe?t(X,da.wireframeLinewidth,da.wireframeLinecap,da.wireframeLinejoin):w(X)):da instanceof THREE.MeshNormalMaterial?(X.r=ic(ka.normalWorld.x),X.g=ic(ka.normalWorld.y),X.b=ic(ka.normalWorld.z),q(H,I,N,O,R,ga,M,J),!0===da.wireframe?t(X,da.wireframeLinewidth,da.wireframeLinecap,da.wireframeLinejoin):w(X)):da instanceof THREE.MeshDepthMaterial&&(Ja=l.near,ma=l.far,fa.r=fa.g=fa.b=1-Db(la.positionScreen.z,Ja,ma),ca.r=ca.g=ca.b=1-Db(cb.positionScreen.z, -Ja,ma),Y.r=Y.g=Y.b=1-Db(Ab.positionScreen.z,Ja,ma),ba.r=ba.g=ba.b=1-Db(E.positionScreen.z,Ja,ma),sa=yc(fa,ca,Y,ba),r(H,I,N,O,M,J),na(H,I,N,O,M,J,0,0,1,0,0,1,sa),r(Q,Z,R,ga,L,oa),na(Q,Z,R,ga,L,oa,1,0,1,1,0,1,sa));Sa.addRectangle(Ka)}s.setTransform(1,0,0,1,0,0)}}}; -THREE.ShaderChunk={fog_pars_fragment:"#ifdef USE_FOG\nuniform vec3 fogColor;\n#ifdef FOG_EXP2\nuniform float fogDensity;\n#else\nuniform float fogNear;\nuniform float fogFar;\n#endif\n#endif",fog_fragment:"#ifdef USE_FOG\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n#ifdef FOG_EXP2\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n#else\nfloat fogFactor = smoothstep( fogNear, fogFar, depth );\n#endif\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\nuniform float reflectivity;\nuniform samplerCube envMap;\nuniform float flipEnvMap;\nuniform int combine;\n#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\nuniform bool useRefract;\nuniform float refractionRatio;\n#else\nvarying vec3 vReflect;\n#endif\n#endif", -envmap_fragment:"#ifdef USE_ENVMAP\nvec3 reflectVec;\n#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\nvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\nif ( useRefract ) {\nreflectVec = refract( cameraToVertex, normal, refractionRatio );\n} else { \nreflectVec = reflect( cameraToVertex, normal );\n}\n#else\nreflectVec = vReflect;\n#endif\n#ifdef DOUBLE_SIDED\nfloat flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );\nvec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n#else\nvec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n#endif\n#ifdef GAMMA_INPUT\ncubeColor.xyz *= cubeColor.xyz;\n#endif\nif ( combine == 1 ) {\ngl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularStrength * reflectivity );\n} else if ( combine == 2 ) {\ngl_FragColor.xyz += cubeColor.xyz * specularStrength * reflectivity;\n} else {\ngl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * cubeColor.xyz, specularStrength * reflectivity );\n}\n#endif", +THREE.Scene.prototype.__removeObject=function(a){if(a instanceof THREE.Light){var b=this.__lights.indexOf(a);-1!==b&&this.__lights.splice(b,1)}else a instanceof THREE.Camera||(b=this.__objects.indexOf(a),-1!==b&&(this.__objects.splice(b,1),this.__objectsRemoved.push(a),b=this.__objectsAdded.indexOf(a),-1!==b&&this.__objectsAdded.splice(b,1)));for(b=0;bJ&&t.clearRect(ua.min.x|0,ua.min.y|0,ua.max.x-ua.min.x|0,ua.max.y-ua.min.y|0),0=h||(h*=f.intensity,c.add(Qa.multiplyScalar(h)))}else f instanceof THREE.PointLight&&(g=bb.getPositionFromMatrix(f.matrixWorld),h=b.dot(bb.subVectors(g,a).normalize()),0>=h||(h*=0==f.distance?1:1-Math.min(a.distanceTo(g)/f.distance,1),0!=h&&(h*=f.intensity,c.add(Qa.multiplyScalar(h)))))}}function z(a,d,e,f,g,h,k,i){m.info.render.vertices+= +3;m.info.render.faces++;b(i.opacity);c(i.blending);A=a.positionScreen.x;ca=a.positionScreen.y;ja=d.positionScreen.x;na=d.positionScreen.y;N=e.positionScreen.x;fa=e.positionScreen.y;y(A,ca,ja,na,N,fa);(i instanceof THREE.MeshLambertMaterial||i instanceof THREE.MeshPhongMaterial)&&null===i.map?(ha.copy(i.color),ia.copy(i.emissive),i.vertexColors===THREE.FaceColors&&ha.multiply(k.color),!1===i.wireframe&&i.shading==THREE.SmoothShading&&3==k.vertexNormalsLength?(ga.copy(tb),W.copy(tb),da.copy(tb),q(k.v1.positionWorld, +k.vertexNormalsModel[0],ga),q(k.v2.positionWorld,k.vertexNormalsModel[1],W),q(k.v3.positionWorld,k.vertexNormalsModel[2],da),ga.multiply(ha).add(ia),W.multiply(ha).add(ia),da.multiply(ha).add(ia),la.addColors(W,da).multiplyScalar(0.5),Aa=H(ga,W,da,la),J(A,ca,ja,na,N,fa,0,0,1,0,0,1,Aa)):(Z.copy(tb),q(k.centroidModel,k.normalModel,Z),Z.multiply(ha).add(ia),!0===i.wireframe?E(Z,i.wireframeLinewidth,i.wireframeLinecap,i.wireframeLinejoin):F(Z))):i instanceof THREE.MeshBasicMaterial||i instanceof THREE.MeshLambertMaterial|| +i instanceof THREE.MeshPhongMaterial?null!==i.map?i.map.mapping instanceof THREE.UVMapping&&(Sa=k.uvs[0],C(A,ca,ja,na,N,fa,Sa[f].x,Sa[f].y,Sa[g].x,Sa[g].y,Sa[h].x,Sa[h].y,i.map)):null!==i.envMap?i.envMap.mapping instanceof THREE.SphericalReflectionMapping&&(bb.copy(k.vertexNormalsModelView[f]),sb=0.5*bb.x+0.5,Nb=0.5*bb.y+0.5,bb.copy(k.vertexNormalsModelView[g]),Kb=0.5*bb.x+0.5,Ob=0.5*bb.y+0.5,bb.copy(k.vertexNormalsModelView[h]),Tb=0.5*bb.x+0.5,Ub=0.5*bb.y+0.5,C(A,ca,ja,na,N,fa,sb,Nb,Kb,Ob,Tb,Ub, +i.envMap)):(Z.copy(i.color),i.vertexColors===THREE.FaceColors&&Z.multiply(k.color),!0===i.wireframe?E(Z,i.wireframeLinewidth,i.wireframeLinecap,i.wireframeLinejoin):F(Z)):i instanceof THREE.MeshDepthMaterial?(Xa=n.near,Ra=n.far,ga.r=ga.g=ga.b=1-j(a.positionScreen.z*a.positionScreen.w,Xa,Ra),W.r=W.g=W.b=1-j(d.positionScreen.z*d.positionScreen.w,Xa,Ra),da.r=da.g=da.b=1-j(e.positionScreen.z*e.positionScreen.w,Xa,Ra),la.addColors(W,da).multiplyScalar(0.5),Aa=H(ga,W,da,la),J(A,ca,ja,na,N,fa,0,0,1,0,0, +1,Aa)):i instanceof THREE.MeshNormalMaterial&&(i.shading==THREE.FlatShading?(a=k.normalModelView,Z.setRGB(a.x,a.y,a.z).multiplyScalar(0.5).addScalar(0.5),!0===i.wireframe?E(Z,i.wireframeLinewidth,i.wireframeLinecap,i.wireframeLinejoin):F(Z)):i.shading==THREE.SmoothShading&&(a=k.vertexNormalsModelView[f],ga.setRGB(a.x,a.y,a.z).multiplyScalar(0.5).addScalar(0.5),a=k.vertexNormalsModelView[g],W.setRGB(a.x,a.y,a.z).multiplyScalar(0.5).addScalar(0.5),a=k.vertexNormalsModelView[h],da.setRGB(a.x,a.y,a.z).multiplyScalar(0.5).addScalar(0.5), +la.addColors(W,da).multiplyScalar(0.5),Aa=H(ga,W,da,la),J(A,ca,ja,na,N,fa,0,0,1,0,0,1,Aa)))}function y(a,b,c,d,e,f){t.beginPath();t.moveTo(a,b);t.lineTo(c,d);t.lineTo(e,f);t.closePath()}function B(a,b,c,d,e,f,g,h){t.beginPath();t.moveTo(a,b);t.lineTo(c,d);t.lineTo(e,f);t.lineTo(g,h);t.closePath()}function E(a,b,c,h){d(b);e(c);f(h);g(a.getStyle());t.stroke();Ja.expandByScalar(2*b)}function F(a){h(a.getStyle());t.fill()}function C(a,b,c,d,e,f,g,i,k,xa,j,l,p){if(!(p instanceof THREE.DataTexture||void 0=== +p.image||0==p.image.width)){if(!0===p.needsUpdate){var m=p.wrapS==THREE.RepeatWrapping,Ya=p.wrapT==THREE.RepeatWrapping;kb[p.id]=t.createPattern(p.image,!0===m&&!0===Ya?"repeat":!0===m&&!1===Ya?"repeat-x":!1===m&&!0===Ya?"repeat-y":"no-repeat");p.needsUpdate=!1}void 0===kb[p.id]?h("rgba(0,0,0,1)"):h(kb[p.id]);var m=p.offset.x/p.repeat.x,Ya=p.offset.y/p.repeat.y,n=p.image.width*p.repeat.x,q=p.image.height*p.repeat.y,g=(g+m)*n,i=(1-i+Ya)*q,c=c-a,d=d-b,e=e-a,f=f-b,k=(k+m)*n-g,xa=(1-xa+Ya)*q-i,j=(j+m)* +n-g,l=(1-l+Ya)*q-i,m=k*l-j*xa;0===m?(void 0===oa[p.id]&&(b=document.createElement("canvas"),b.width=p.image.width,b.height=p.image.height,b=b.getContext("2d"),b.drawImage(p.image,0,0),oa[p.id]=b.getImageData(0,0,p.image.width,p.image.height).data),b=oa[p.id],g=4*(Math.floor(g)+Math.floor(i)*p.image.width),Z.setRGB(b[g]/255,b[g+1]/255,b[g+2]/255),F(Z)):(m=1/m,p=(l*c-xa*e)*m,xa=(l*d-xa*f)*m,c=(k*e-j*c)*m,d=(k*f-j*d)*m,a=a-p*g-c*i,g=b-xa*g-d*i,t.save(),t.transform(p,xa,c,d,a,g),t.fill(),t.restore())}} +function J(a,b,c,d,e,f,g,h,i,k,xa,j,p){var m,l;m=p.width-1;l=p.height-1;g*=m;h*=l;c-=a;d-=b;e-=a;f-=b;i=i*m-g;k=k*l-h;xa=xa*m-g;j=j*l-h;l=1/(i*j-xa*k);m=(j*c-k*e)*l;k=(j*d-k*f)*l;c=(i*e-xa*c)*l;d=(i*f-xa*d)*l;a=a-m*g-c*h;b=b-k*g-d*h;t.save();t.transform(m,k,c,d,a,b);t.clip();t.drawImage(p,0,0);t.restore()}function H(a,b,c,d){Ua[0]=255*a.r|0;Ua[1]=255*a.g|0;Ua[2]=255*a.b|0;Ua[4]=255*b.r|0;Ua[5]=255*b.g|0;Ua[6]=255*b.b|0;Ua[8]=255*c.r|0;Ua[9]=255*c.g|0;Ua[10]=255*c.b|0;Ua[12]=255*d.r|0;Ua[13]=255*d.g| +0;Ua[14]=255*d.b|0;k.putImageData(Bb,0,0);Va.drawImage(Ab,0,0);return lb}function G(a,b){var c=b.x-a.x,d=b.y-a.y,e=c*c+d*d;0!==e&&(e=1/Math.sqrt(e),c*=e,d*=e,b.x+=c,b.y+=d,a.x-=c,a.y-=d)}if(!1===n instanceof THREE.Camera)console.error("THREE.CanvasRenderer.render: camera is not an instance of THREE.Camera.");else{!0===this.autoClear&&this.clear();t.setTransform(1,0,0,-1,u,x);m.info.render.vertices=0;m.info.render.faces=0;p=s.projectScene(a,n,this.sortObjects,this.sortElements);l=p.elements;r=p.lights; +tb.setRGB(0,0,0);Na.setRGB(0,0,0);ra.setRGB(0,0,0);for(var K=0,V=r.length;K>1,Pc=Pb.height>>1,Ya=L.scale.x*u,vb=L.scale.y*x,xa=Ya*Oc,mb=vb*Pc,Ja.min.set(P.x-xa,P.y-mb),Ja.max.set(P.x+xa,P.y+mb),!1===Ta.isIntersectionBox(Ja)? +Ja.makeEmpty():(t.save(),t.translate(P.x,P.y),t.rotate(-L.rotation),t.scale(Ya,-vb),t.translate(-Oc,-Pc),t.drawImage(Pb,0,0),t.restore())):U instanceof THREE.ParticleCanvasMaterial&&(xa=L.scale.x*u,mb=L.scale.y*x,Ja.min.set(P.x-xa,P.y-mb),Ja.max.set(P.x+xa,P.y+mb),!1===Ta.isIntersectionBox(Ja)?Ja.makeEmpty():(g(U.color.getStyle()),h(U.color.getStyle()),t.save(),t.translate(P.x,P.y),t.rotate(-L.rotation),t.scale(xa,mb),U.program(t),t.restore()))}else if(L instanceof THREE.RenderableLine){if(I=L.v1, +M=L.v2,I.positionScreen.x*=u,I.positionScreen.y*=x,M.positionScreen.x*=u,M.positionScreen.y*=x,Ja.setFromPoints([I.positionScreen,M.positionScreen]),!0===Ta.isIntersectionBox(Ja))if(P=I,xa=M,b(U.opacity),c(U.blending),t.beginPath(),t.moveTo(P.positionScreen.x,P.positionScreen.y),t.lineTo(xa.positionScreen.x,xa.positionScreen.y),U instanceof THREE.LineBasicMaterial){d(U.linewidth);e(U.linecap);f(U.linejoin);if(U.vertexColors!==THREE.VertexColors)g(U.color.getStyle());else if(mb=L.vertexColors[0].getStyle(), +L=L.vertexColors[1].getStyle(),mb===L)g(mb);else{try{var qc=t.createLinearGradient(P.positionScreen.x,P.positionScreen.y,xa.positionScreen.x,xa.positionScreen.y);qc.addColorStop(0,mb);qc.addColorStop(1,L)}catch(ed){qc=mb}g(qc)}t.stroke();Ja.expandByScalar(2*U.linewidth)}else U instanceof THREE.LineDashedMaterial&&(d(U.linewidth),e(U.linecap),f(U.linejoin),g(U.color.getStyle()),i(U.dashSize,U.gapSize),t.stroke(),Ja.expandByScalar(2*U.linewidth),i(null,null))}else if(L instanceof THREE.RenderableFace3){I= +L.v1;M=L.v2;R=L.v3;if(-1>I.positionScreen.z||1M.positionScreen.z||1R.positionScreen.z||1I.positionScreen.z||1M.positionScreen.z||1R.positionScreen.z||1ea.positionScreen.z||1 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_HEMI_LIGHTS > 0\nuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\nuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\nuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif", lights_lambert_vertex:"vLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\nvLightBack = vec3( 0.0 );\n#endif\ntransformedNormal = normalize( transformedNormal );\n#if MAX_DIR_LIGHTS > 0\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( transformedNormal, dirVector );\nvec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\ndirectionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\ndirectionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n#ifdef DOUBLE_SIDED\nvLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n#endif\n}\n#endif\n#if MAX_POINT_LIGHTS > 0\nfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\nfloat dotProduct = dot( transformedNormal, lVector );\nvec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\npointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\npointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;\n#ifdef DOUBLE_SIDED\nvLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;\n#endif\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\nif ( spotEffect > spotLightAngleCos[ i ] ) {\nspotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );\nfloat lDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\nfloat dotProduct = dot( transformedNormal, lVector );\nvec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\nspotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\nspotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += spotLightColor[ i ] * spotLightWeighting * lDistance * spotEffect;\n#ifdef DOUBLE_SIDED\nvLightBack += spotLightColor[ i ] * spotLightWeightingBack * lDistance * spotEffect;\n#endif\n}\n}\n#endif\n#if MAX_HEMI_LIGHTS > 0\nfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );\nvec3 lVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( transformedNormal, lVector );\nfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\nfloat hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\nvLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n#ifdef DOUBLE_SIDED\nvLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n#endif\n}\n#endif\nvLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;\n#ifdef DOUBLE_SIDED\nvLightBack = vLightBack * diffuse + ambient * ambientLightColor + emissive;\n#endif", lights_phong_pars_vertex:"#ifndef PHONG_PER_PIXEL\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\nvarying vec4 vPointLight[ MAX_POINT_LIGHTS ];\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\nvarying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )\nvarying vec3 vWorldPosition;\n#endif", lights_phong_vertex:"#ifndef PHONG_PER_PIXEL\n#if MAX_POINT_LIGHTS > 0\nfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nvPointLight[ i ] = vec4( lVector, lDistance );\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\nvSpotLight[ i ] = vec4( lVector, lDistance );\n}\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )\nvWorldPosition = worldPosition.xyz;\n#endif", lights_phong_pars_fragment:"uniform vec3 ambientLightColor;\n#if MAX_DIR_LIGHTS > 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_HEMI_LIGHTS > 0\nuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n#ifdef PHONG_PER_PIXEL\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#else\nvarying vec4 vPointLight[ MAX_POINT_LIGHTS ];\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\nuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\nuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n#ifdef PHONG_PER_PIXEL\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n#else\nvarying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )\nvarying vec3 vWorldPosition;\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;", -lights_phong_fragment:"vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\n#ifdef DOUBLE_SIDED\nnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n#endif\n#ifdef USE_NORMALMAP\nnormal = perturbNormal2Arb( -viewPosition, normal );\n#elif defined( USE_BUMPMAP )\nnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n#if MAX_POINT_LIGHTS > 0\nvec3 pointDiffuse = vec3( 0.0 );\nvec3 pointSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n#ifdef PHONG_PER_PIXEL\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz + vViewPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\n#else\nvec3 lVector = normalize( vPointLight[ i ].xyz );\nfloat lDistance = vPointLight[ i ].w;\n#endif\nfloat dotProduct = dot( normal, lVector );\n#ifdef WRAP_AROUND\nfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n#else\nfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n#endif\npointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;\nvec3 pointHalfVector = normalize( lVector + viewPosition );\nfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\nfloat pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, pointHalfVector ), 5.0 );\npointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;\n#else\npointSpecular += specular * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;\n#endif\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nvec3 spotDiffuse = vec3( 0.0 );\nvec3 spotSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n#ifdef PHONG_PER_PIXEL\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz + vViewPosition.xyz;\nfloat lDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\n#else\nvec3 lVector = normalize( vSpotLight[ i ].xyz );\nfloat lDistance = vSpotLight[ i ].w;\n#endif\nfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\nif ( spotEffect > spotLightAngleCos[ i ] ) {\nspotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );\nfloat dotProduct = dot( normal, lVector );\n#ifdef WRAP_AROUND\nfloat spotDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n#else\nfloat spotDiffuseWeight = max( dotProduct, 0.0 );\n#endif\nspotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;\nvec3 spotHalfVector = normalize( lVector + viewPosition );\nfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\nfloat spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, spotHalfVector ), 5.0 );\nspotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;\n#else\nspotSpecular += specular * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * spotEffect;\n#endif\n}\n}\n#endif\n#if MAX_DIR_LIGHTS > 0\nvec3 dirDiffuse = vec3( 0.0 );\nvec3 dirSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, dirVector );\n#ifdef WRAP_AROUND\nfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n#else\nfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n#endif\ndirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\nvec3 dirHalfVector = normalize( dirVector + viewPosition );\nfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\nfloat dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );\ndirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n#else\ndirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;\n#endif\n}\n#endif\n#if MAX_HEMI_LIGHTS > 0\nvec3 hemiDiffuse = vec3( 0.0 );\nvec3 hemiSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );\nvec3 lVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, lVector );\nfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\nvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\nhemiDiffuse += diffuse * hemiColor;\nvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\nfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\nfloat hemiSpecularWeightSky = specularStrength * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );\nvec3 lVectorGround = -lVector;\nvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\nfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\nfloat hemiSpecularWeightGround = specularStrength * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat dotProductGround = dot( normal, lVectorGround );\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );\nvec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );\nhemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n#else\nhemiSpecular += specular * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;\n#endif\n}\n#endif\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n#if MAX_DIR_LIGHTS > 0\ntotalDiffuse += dirDiffuse;\ntotalSpecular += dirSpecular;\n#endif\n#if MAX_HEMI_LIGHTS > 0\ntotalDiffuse += hemiDiffuse;\ntotalSpecular += hemiSpecular;\n#endif\n#if MAX_POINT_LIGHTS > 0\ntotalDiffuse += pointDiffuse;\ntotalSpecular += pointSpecular;\n#endif\n#if MAX_SPOT_LIGHTS > 0\ntotalDiffuse += spotDiffuse;\ntotalSpecular += spotSpecular;\n#endif\n#ifdef METAL\ngl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;\n#endif", +lights_phong_fragment:"vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\n#ifdef DOUBLE_SIDED\nnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n#endif\n#ifdef USE_NORMALMAP\nnormal = perturbNormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\nnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n#if MAX_POINT_LIGHTS > 0\nvec3 pointDiffuse = vec3( 0.0 );\nvec3 pointSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n#ifdef PHONG_PER_PIXEL\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz + vViewPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\n#else\nvec3 lVector = normalize( vPointLight[ i ].xyz );\nfloat lDistance = vPointLight[ i ].w;\n#endif\nfloat dotProduct = dot( normal, lVector );\n#ifdef WRAP_AROUND\nfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n#else\nfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n#endif\npointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;\nvec3 pointHalfVector = normalize( lVector + viewPosition );\nfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\nfloat pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, pointHalfVector ), 5.0 );\npointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;\n#else\npointSpecular += specular * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;\n#endif\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nvec3 spotDiffuse = vec3( 0.0 );\nvec3 spotSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n#ifdef PHONG_PER_PIXEL\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz + vViewPosition.xyz;\nfloat lDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\n#else\nvec3 lVector = normalize( vSpotLight[ i ].xyz );\nfloat lDistance = vSpotLight[ i ].w;\n#endif\nfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\nif ( spotEffect > spotLightAngleCos[ i ] ) {\nspotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );\nfloat dotProduct = dot( normal, lVector );\n#ifdef WRAP_AROUND\nfloat spotDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n#else\nfloat spotDiffuseWeight = max( dotProduct, 0.0 );\n#endif\nspotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;\nvec3 spotHalfVector = normalize( lVector + viewPosition );\nfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\nfloat spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, spotHalfVector ), 5.0 );\nspotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;\n#else\nspotSpecular += specular * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * spotEffect;\n#endif\n}\n}\n#endif\n#if MAX_DIR_LIGHTS > 0\nvec3 dirDiffuse = vec3( 0.0 );\nvec3 dirSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, dirVector );\n#ifdef WRAP_AROUND\nfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n#else\nfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n#endif\ndirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\nvec3 dirHalfVector = normalize( dirVector + viewPosition );\nfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\nfloat dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );\ndirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n#else\ndirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;\n#endif\n}\n#endif\n#if MAX_HEMI_LIGHTS > 0\nvec3 hemiDiffuse = vec3( 0.0 );\nvec3 hemiSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );\nvec3 lVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, lVector );\nfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\nvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\nhemiDiffuse += diffuse * hemiColor;\nvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\nfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\nfloat hemiSpecularWeightSky = specularStrength * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );\nvec3 lVectorGround = -lVector;\nvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\nfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\nfloat hemiSpecularWeightGround = specularStrength * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat dotProductGround = dot( normal, lVectorGround );\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );\nvec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );\nhemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n#else\nhemiSpecular += specular * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;\n#endif\n}\n#endif\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n#if MAX_DIR_LIGHTS > 0\ntotalDiffuse += dirDiffuse;\ntotalSpecular += dirSpecular;\n#endif\n#if MAX_HEMI_LIGHTS > 0\ntotalDiffuse += hemiDiffuse;\ntotalSpecular += hemiSpecular;\n#endif\n#if MAX_POINT_LIGHTS > 0\ntotalDiffuse += pointDiffuse;\ntotalSpecular += pointSpecular;\n#endif\n#if MAX_SPOT_LIGHTS > 0\ntotalDiffuse += spotDiffuse;\ntotalSpecular += spotSpecular;\n#endif\n#ifdef METAL\ngl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;\n#endif", color_pars_fragment:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_fragment:"#ifdef USE_COLOR\ngl_FragColor = gl_FragColor * vec4( vColor, opacity );\n#endif",color_pars_vertex:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n#ifdef GAMMA_INPUT\nvColor = color * color;\n#else\nvColor = color;\n#endif\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n#ifdef BONE_TEXTURE\nuniform sampler2D boneTexture;\nmat4 getBoneMatrix( const in float i ) {\nfloat j = i * 4.0;\nfloat x = mod( j, N_BONE_PIXEL_X );\nfloat y = floor( j / N_BONE_PIXEL_X );\nconst float dx = 1.0 / N_BONE_PIXEL_X;\nconst float dy = 1.0 / N_BONE_PIXEL_Y;\ny = dy * ( y + 0.5 );\nvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\nvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\nvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\nvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\nmat4 bone = mat4( v1, v2, v3, v4 );\nreturn bone;\n}\n#else\nuniform mat4 boneGlobalMatrices[ MAX_BONES ];\nmat4 getBoneMatrix( const in float i ) {\nmat4 bone = boneGlobalMatrices[ int(i) ];\nreturn bone;\n}\n#endif\n#endif", skinbase_vertex:"#ifdef USE_SKINNING\nmat4 boneMatX = getBoneMatrix( skinIndex.x );\nmat4 boneMatY = getBoneMatrix( skinIndex.y );\n#endif",skinning_vertex:"#ifdef USE_SKINNING\n#ifdef USE_MORPHTARGETS\nvec4 skinVertex = vec4( morphed, 1.0 );\n#else\nvec4 skinVertex = vec4( position, 1.0 );\n#endif\nvec4 skinned = boneMatX * skinVertex * skinWeight.x;\nskinned \t += boneMatY * skinVertex * skinWeight.y;\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n#ifndef USE_MORPHNORMALS\nuniform float morphTargetInfluences[ 8 ];\n#else\nuniform float morphTargetInfluences[ 4 ];\n#endif\n#endif", morphtarget_vertex:"#ifdef USE_MORPHTARGETS\nvec3 morphed = vec3( 0.0 );\nmorphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\nmorphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\nmorphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\nmorphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n#ifndef USE_MORPHNORMALS\nmorphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\nmorphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\nmorphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\nmorphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n#endif\nmorphed += position;\n#endif", default_vertex:"vec4 mvPosition;\n#ifdef USE_SKINNING\nmvPosition = modelViewMatrix * skinned;\n#endif\n#if !defined( USE_SKINNING ) && defined( USE_MORPHTARGETS )\nmvPosition = modelViewMatrix * vec4( morphed, 1.0 );\n#endif\n#if !defined( USE_SKINNING ) && ! defined( USE_MORPHTARGETS )\nmvPosition = modelViewMatrix * vec4( position, 1.0 );\n#endif\ngl_Position = projectionMatrix * mvPosition;",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\nvec3 morphedNormal = vec3( 0.0 );\nmorphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\nmorphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\nmorphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\nmorphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\nmorphedNormal += normal;\n#endif", skinnormal_vertex:"#ifdef USE_SKINNING\nmat4 skinMatrix = skinWeight.x * boneMatX;\nskinMatrix \t+= skinWeight.y * boneMatY;\n#ifdef USE_MORPHNORMALS\nvec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );\n#else\nvec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );\n#endif\n#endif",defaultnormal_vertex:"vec3 objectNormal;\n#ifdef USE_SKINNING\nobjectNormal = skinnedNormal.xyz;\n#endif\n#if !defined( USE_SKINNING ) && defined( USE_MORPHNORMALS )\nobjectNormal = morphedNormal;\n#endif\n#if !defined( USE_SKINNING ) && ! defined( USE_MORPHNORMALS )\nobjectNormal = normal;\n#endif\n#ifdef FLIP_SIDED\nobjectNormal = -objectNormal;\n#endif\nvec3 transformedNormal = normalMatrix * objectNormal;", -shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\nuniform sampler2D shadowMap[ MAX_SHADOWS ];\nuniform vec2 shadowMapSize[ MAX_SHADOWS ];\nuniform float shadowDarkness[ MAX_SHADOWS ];\nuniform float shadowBias[ MAX_SHADOWS ];\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nfloat unpackDepth( const in vec4 rgba_depth ) {\nconst vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\nfloat depth = dot( rgba_depth, bit_shift );\nreturn depth;\n}\n#endif",shadowmap_fragment:"#ifdef USE_SHADOWMAP\n#ifdef SHADOWMAP_DEBUG\nvec3 frustumColors[3];\nfrustumColors[0] = vec3( 1.0, 0.5, 0.0 );\nfrustumColors[1] = vec3( 0.0, 1.0, 0.8 );\nfrustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n#endif\n#ifdef SHADOWMAP_CASCADE\nint inFrustumCount = 0;\n#endif\nfloat fDepth;\nvec3 shadowColor = vec3( 1.0 );\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\nbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\nbool inFrustum = all( inFrustumVec );\n#ifdef SHADOWMAP_CASCADE\ninFrustumCount += int( inFrustum );\nbvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n#else\nbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n#endif\nbool frustumTest = all( frustumTestVec );\nif ( frustumTest ) {\nshadowCoord.z += shadowBias[ i ];\n#ifdef SHADOWMAP_SOFT\nfloat shadow = 0.0;\nconst float shadowDelta = 1.0 / 9.0;\nfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\nfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\nfloat dx0 = -1.25 * xPixelOffset;\nfloat dy0 = -1.25 * yPixelOffset;\nfloat dx1 = 1.25 * xPixelOffset;\nfloat dy1 = 1.25 * yPixelOffset;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n#else\nvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n#endif\n}\n#ifdef SHADOWMAP_DEBUG\n#ifdef SHADOWMAP_CASCADE\nif ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n#else\nif ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n#endif\n#endif\n}\n#ifdef GAMMA_OUTPUT\nshadowColor *= shadowColor;\n#endif\ngl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n#endif", +shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\nuniform sampler2D shadowMap[ MAX_SHADOWS ];\nuniform vec2 shadowMapSize[ MAX_SHADOWS ];\nuniform float shadowDarkness[ MAX_SHADOWS ];\nuniform float shadowBias[ MAX_SHADOWS ];\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nfloat unpackDepth( const in vec4 rgba_depth ) {\nconst vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\nfloat depth = dot( rgba_depth, bit_shift );\nreturn depth;\n}\n#endif",shadowmap_fragment:"#ifdef USE_SHADOWMAP\n#ifdef SHADOWMAP_DEBUG\nvec3 frustumColors[3];\nfrustumColors[0] = vec3( 1.0, 0.5, 0.0 );\nfrustumColors[1] = vec3( 0.0, 1.0, 0.8 );\nfrustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n#endif\n#ifdef SHADOWMAP_CASCADE\nint inFrustumCount = 0;\n#endif\nfloat fDepth;\nvec3 shadowColor = vec3( 1.0 );\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\nbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\nbool inFrustum = all( inFrustumVec );\n#ifdef SHADOWMAP_CASCADE\ninFrustumCount += int( inFrustum );\nbvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n#else\nbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n#endif\nbool frustumTest = all( frustumTestVec );\nif ( frustumTest ) {\nshadowCoord.z += shadowBias[ i ];\n#if defined( SHADOWMAP_TYPE_PCF )\nfloat shadow = 0.0;\nconst float shadowDelta = 1.0 / 9.0;\nfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\nfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\nfloat dx0 = -1.25 * xPixelOffset;\nfloat dy0 = -1.25 * yPixelOffset;\nfloat dx1 = 1.25 * xPixelOffset;\nfloat dy1 = 1.25 * yPixelOffset;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\nfloat shadow = 0.0;\nfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\nfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\nfloat dx0 = -1.0 * xPixelOffset;\nfloat dy0 = -1.0 * yPixelOffset;\nfloat dx1 = 1.0 * xPixelOffset;\nfloat dy1 = 1.0 * yPixelOffset;\nmat3 shadowKernel;\nmat3 depthKernel;\ndepthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\ndepthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\ndepthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\ndepthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\ndepthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\ndepthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\ndepthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\ndepthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\ndepthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\nvec3 shadowZ = vec3( shadowCoord.z );\nshadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));\nshadowKernel[0] *= vec3(0.25);\nshadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));\nshadowKernel[1] *= vec3(0.25);\nshadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));\nshadowKernel[2] *= vec3(0.25);\nvec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\nshadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\nshadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\nvec4 shadowValues;\nshadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\nshadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\nshadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\nshadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\nshadow = dot( shadowValues, vec4( 1.0 ) );\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n#else\nvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n#endif\n}\n#ifdef SHADOWMAP_DEBUG\n#ifdef SHADOWMAP_CASCADE\nif ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n#else\nif ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n#endif\n#endif\n}\n#ifdef GAMMA_OUTPUT\nshadowColor *= shadowColor;\n#endif\ngl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n#endif", shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n#endif",shadowmap_vertex:"#ifdef USE_SHADOWMAP\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n}\n#endif",alphatest_fragment:"#ifdef ALPHATEST\nif ( gl_FragColor.a < ALPHATEST ) discard;\n#endif",linear_to_gamma_fragment:"#ifdef GAMMA_OUTPUT\ngl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n#endif"}; THREE.UniformsUtils={merge:function(a){var b,c,d,e={};for(b=0;b dashSize ) {\ndiscard;\n}\ngl_FragColor = vec4( diffuse, opacity );",THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},depthRGBA:{uniforms:{},vertexShader:[THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex, -THREE.ShaderChunk.default_vertex,"}"].join("\n"),fragmentShader:"vec4 pack_depth( const in float depth ) {\nconst vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\nconst vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\nvec4 res = fract( depth * bit_shift );\nres -= res.xxyz * bit_mask;\nreturn res;\n}\nvoid main() {\ngl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n}"}}; -THREE.WebGLRenderer=function(a){function b(a){if(a.__webglCustomAttributesList)for(var b in a.__webglCustomAttributesList)k.deleteBuffer(a.__webglCustomAttributesList[b].buffer)}function c(a,b){var c=a.vertices.length,d=b.material;if(d.attributes){void 0===a.__webglCustomAttributesList&&(a.__webglCustomAttributesList=[]);for(var e in d.attributes){var f=d.attributes[e];if(!f.__webglInitialized||f.createUniqueBuffers){f.__webglInitialized=!0;var g=1;"v2"===f.type?g=2:"v3"===f.type?g=3:"v4"===f.type? -g=4:"c"===f.type&&(g=3);f.size=g;f.array=new Float32Array(c*g);f.buffer=k.createBuffer();f.buffer.belongsToAttribute=e;f.needsUpdate=!0}a.__webglCustomAttributesList.push(f)}}}function d(a,b){var c=b.geometry,d=a.faces3,h=a.faces4,i=3*d.length+4*h.length,j=1*d.length+2*h.length,h=3*d.length+4*h.length,d=e(b,a),l=g(d),n=f(d),m=d.vertexColors?d.vertexColors:!1;a.__vertexArray=new Float32Array(3*i);n&&(a.__normalArray=new Float32Array(3*i));c.hasTangents&&(a.__tangentArray=new Float32Array(4*i));m&& -(a.__colorArray=new Float32Array(3*i));if(l){if(0l;l++)L.autoScaleCubemaps&&!f?(n=j,m=l,r=c.image[l],t= -Qc,r.width<=t&&r.height<=t||(w=Math.max(r.width,r.height),q=Math.floor(r.width*t/w),t=Math.floor(r.height*t/w),w=document.createElement("canvas"),w.width=q,w.height=t,w.getContext("2d").drawImage(r,0,0,r.width,r.height,0,0,q,t),r=w),n[m]=r):j[l]=c.image[l];l=j[0];n=0===(l.width&l.width-1)&&0===(l.height&l.height-1);m=H(c.format);r=H(c.type);P(k.TEXTURE_CUBE_MAP,c,n);for(l=0;6>l;l++)if(f){t=j[l].mipmaps;w=0;for(z=t.length;w=xc&&console.warn("Trying to use "+a+" texture units while this GPU supports only "+xc);Aa+=1;return a}function A(a,b){a._modelViewMatrix.multiply(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getInverse(a._modelViewMatrix);a._normalMatrix.transpose()}function v(a,b,c, -d){a[b]=c.r*c.r*d;a[b+1]=c.g*c.g*d;a[b+2]=c.b*c.b*d}function u(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function D(a,b,c){jb!==a&&(a?k.enable(k.POLYGON_OFFSET_FILL):k.disable(k.POLYGON_OFFSET_FILL),jb=a);if(a&&(Bb!==b||Cb!==c))k.polygonOffset(b,c),Bb=b,Cb=c}function C(a){for(var a=a.split("\n"),b=0,c=a.length;bb;b++)k.deleteFramebuffer(a.__webglFramebuffer[b]),k.deleteRenderbuffer(a.__webglRenderbuffer[b]); -else k.deleteFramebuffer(a.__webglFramebuffer),k.deleteRenderbuffer(a.__webglRenderbuffer)};this.deallocateMaterial=function(a){var b=a.program;if(b){a.program=void 0;var c,d,e=!1,a=0;for(c=oa.length;ad.numSupportedMorphTargets?(h.sort(m),h.length=d.numSupportedMorphTargets):h.length>d.numSupportedMorphNormals?h.sort(m): -0===h.length&&h.push([0,0]);for(i=0;iwa;wa++)ac=eb[wa],wb[Za]=ac.x,wb[Za+1]= -ac.y,wb[Za+2]=ac.z,Za+=3;else for(wa=0;3>wa;wa++)wb[Za]=bb.x,wb[Za+1]=bb.y,wb[Za+2]=bb.z,Za+=3;F=0;for($=ua.length;F<$;F++)if(S=$a[ua[F]],eb=S.vertexNormals,bb=S.normal,4===eb.length&&lb)for(wa=0;4>wa;wa++)ac=eb[wa],wb[Za]=ac.x,wb[Za+1]=ac.y,wb[Za+2]=ac.z,Za+=3;else for(wa=0;4>wa;wa++)wb[Za]=bb.x,wb[Za+1]=bb.y,wb[Za+2]=bb.z,Za+=3;k.bindBuffer(k.ARRAY_BUFFER,ra.__webglNormalBuffer);k.bufferData(k.ARRAY_BUFFER,wb,Ea)}if(oc&&Vc&&ob){F=0;for($=ta.length;F<$;F++)if(ab=ta[F],jb=Vc[ab],void 0!==jb)for(wa= -0;3>wa;wa++)kc=jb[wa],pc[Xb]=kc.u,pc[Xb+1]=kc.v,Xb+=2;F=0;for($=ua.length;F<$;F++)if(ab=ua[F],jb=Vc[ab],void 0!==jb)for(wa=0;4>wa;wa++)kc=jb[wa],pc[Xb]=kc.u,pc[Xb+1]=kc.v,Xb+=2;0wa;wa++)lc=kb[wa],qc[Yb]=lc.u,qc[Yb+1]=lc.v,Yb+=2;F=0;for($=ua.length;F<$;F++)if(ab=ua[F],kb=Wc[ab],void 0!==kb)for(wa=0;4>wa;wa++)lc=kb[wa],qc[Yb]= -lc.u,qc[Yb+1]=lc.v,Yb+=2;0f;f++){a.__webglFramebuffer[f]=k.createFramebuffer();a.__webglRenderbuffer[f]=k.createRenderbuffer();k.texImage2D(k.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width, -a.height,0,d,e,null);var g=a,h=k.TEXTURE_CUBE_MAP_POSITIVE_X+f;k.bindFramebuffer(k.FRAMEBUFFER,a.__webglFramebuffer[f]);k.framebufferTexture2D(k.FRAMEBUFFER,k.COLOR_ATTACHMENT0,h,g.__webglTexture,0);B(a.__webglRenderbuffer[f],a)}c&&k.generateMipmap(k.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=k.createFramebuffer(),a.__webglRenderbuffer=k.createRenderbuffer(),k.bindTexture(k.TEXTURE_2D,a.__webglTexture),P(k.TEXTURE_2D,a,c),k.texImage2D(k.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=k.TEXTURE_2D, -k.bindFramebuffer(k.FRAMEBUFFER,a.__webglFramebuffer),k.framebufferTexture2D(k.FRAMEBUFFER,k.COLOR_ATTACHMENT0,d,a.__webglTexture,0),B(a.__webglRenderbuffer,a),c&&k.generateMipmap(k.TEXTURE_2D);b?k.bindTexture(k.TEXTURE_CUBE_MAP,null):k.bindTexture(k.TEXTURE_2D,null);k.bindRenderbuffer(k.RENDERBUFFER,null);k.bindFramebuffer(k.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=kb,a=Oa,d=Sa,e=Ka);b!==ca&&(k.bindFramebuffer(k.FRAMEBUFFER, -b),k.viewport(d,e,c,a),ca=b);lb=c;ab=a};this.shadowMapPlugin=new THREE.ShadowMapPlugin;this.addPrePlugin(this.shadowMapPlugin);this.addPostPlugin(new THREE.SpritePlugin);this.addPostPlugin(new THREE.LensFlarePlugin)}; -THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: -THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0}; -THREE.WebGLRenderTarget.prototype.clone=function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.anisotropy=this.anisotropy;a.minFilter=this.minFilter;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps;return a}; -THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype);THREE.RenderableVertex=function(){this.positionWorld=new THREE.Vector3;this.positionScreen=new THREE.Vector4;this.visible=!0};THREE.RenderableVertex.prototype.copy=function(a){this.positionWorld.copy(a.positionWorld);this.positionScreen.copy(a.positionScreen)}; -THREE.RenderableFace3=function(){this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.v3=new THREE.RenderableVertex;this.centroidWorld=new THREE.Vector3;this.centroidScreen=new THREE.Vector3;this.normalWorld=new THREE.Vector3;this.vertexNormalsWorld=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.vertexNormalsLength=0;this.material=this.color=null;this.uvs=[[]];this.z=null}; -THREE.RenderableFace4=function(){this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.v3=new THREE.RenderableVertex;this.v4=new THREE.RenderableVertex;this.centroidWorld=new THREE.Vector3;this.centroidScreen=new THREE.Vector3;this.normalWorld=new THREE.Vector3;this.vertexNormalsWorld=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.vertexNormalsLength=0;this.material=this.color=null;this.uvs=[[]];this.z=null}; -THREE.RenderableObject=function(){this.z=this.object=null};THREE.RenderableParticle=function(){this.rotation=this.z=this.y=this.x=this.object=null;this.scale=new THREE.Vector2;this.material=null};THREE.RenderableLine=function(){this.z=null;this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.material=null}; -THREE.ColorUtils={adjustHSV:function(a,b,c,d){var e=THREE.ColorUtils.__hsv;a.getHSV(e);e.h=THREE.Math.clamp(e.h+b,0,1);e.s=THREE.Math.clamp(e.s+c,0,1);e.v=THREE.Math.clamp(e.v+d,0,1);a.setHSV(e.h,e.s,e.v)}};THREE.ColorUtils.__hsv={h:0,s:0,v:0}; -THREE.GeometryUtils={merge:function(a,b){var c,d,e=a.vertices.length,f=b instanceof THREE.Mesh?b.geometry:b,g=a.vertices,h=f.vertices,i=a.faces,j=f.faces,l=a.faceVertexUvs[0],f=f.faceVertexUvs[0];b instanceof THREE.Mesh&&(b.matrixAutoUpdate&&b.updateMatrix(),c=b.matrix,d=new THREE.Matrix4,d.extractRotation(c,b.scale));for(var m=0,n=h.length;ma?b(c,e-1):j[e]b||o>b||n>b){i=a.vertices.length;w=e.clone();q=e.clone();p>=o&&p>=n?(j=j.clone(),j.lerpSelf(l,0.5),w.a=f,w.b=i,w.c=h,q.a=i,q.b=g,q.c=h,3===e.vertexNormals.length&&(f=e.vertexNormals[0].clone(),f.lerpSelf(e.vertexNormals[1],0.5),w.vertexNormals[1].copy(f),q.vertexNormals[0].copy(f)),3===e.vertexColors.length&&(f=e.vertexColors[0].clone(),f.lerpSelf(e.vertexColors[1],0.5),w.vertexColors[1].copy(f),q.vertexColors[0].copy(f)),e=0): -o>=p&&o>=n?(j=l.clone(),j.lerpSelf(m,0.5),w.a=f,w.b=g,w.c=i,q.a=i,q.b=h,q.c=f,3===e.vertexNormals.length&&(f=e.vertexNormals[1].clone(),f.lerpSelf(e.vertexNormals[2],0.5),w.vertexNormals[2].copy(f),q.vertexNormals[0].copy(f),q.vertexNormals[1].copy(e.vertexNormals[2]),q.vertexNormals[2].copy(e.vertexNormals[0])),3===e.vertexColors.length&&(f=e.vertexColors[1].clone(),f.lerpSelf(e.vertexColors[2],0.5),w.vertexColors[2].copy(f),q.vertexColors[0].copy(f),q.vertexColors[1].copy(e.vertexColors[2]),q.vertexColors[2].copy(e.vertexColors[0])), -e=1):(j=j.clone(),j.lerpSelf(m,0.5),w.a=f,w.b=g,w.c=i,q.a=i,q.b=g,q.c=h,3===e.vertexNormals.length&&(f=e.vertexNormals[0].clone(),f.lerpSelf(e.vertexNormals[2],0.5),w.vertexNormals[2].copy(f),q.vertexNormals[0].copy(f)),3===e.vertexColors.length&&(f=e.vertexColors[0].clone(),f.lerpSelf(e.vertexColors[2],0.5),w.vertexColors[2].copy(f),q.vertexColors[0].copy(f)),e=2);E.push(w,q);a.vertices.push(j);f=0;for(g=a.faceVertexUvs.length;fb||o>b||s>b||t>b){r=a.vertices.length;z=a.vertices.length+1;w=e.clone();q=e.clone();p>=o&&p>=s&&p>=t||s>=o&&s>=p&&s>=t?(p=j.clone(),p.lerpSelf(l,0.5),l=m.clone(),l.lerpSelf(n,0.5),w.a=f,w.b=r,w.c=z,w.d=i,q.a=r,q.b=g,q.c=h,q.d=z,4===e.vertexNormals.length&&(f=e.vertexNormals[0].clone(),f.lerpSelf(e.vertexNormals[1],0.5),g=e.vertexNormals[2].clone(),g.lerpSelf(e.vertexNormals[3],0.5),w.vertexNormals[1].copy(f), -w.vertexNormals[2].copy(g),q.vertexNormals[0].copy(f),q.vertexNormals[3].copy(g)),4===e.vertexColors.length&&(f=e.vertexColors[0].clone(),f.lerpSelf(e.vertexColors[1],0.5),g=e.vertexColors[2].clone(),g.lerpSelf(e.vertexColors[3],0.5),w.vertexColors[1].copy(f),w.vertexColors[2].copy(g),q.vertexColors[0].copy(f),q.vertexColors[3].copy(g)),e=0):(p=l.clone(),p.lerpSelf(m,0.5),l=n.clone(),l.lerpSelf(j,0.5),w.a=f,w.b=g,w.c=r,w.d=z,q.a=z,q.b=r,q.c=h,q.d=i,4===e.vertexNormals.length&&(f=e.vertexNormals[1].clone(), -f.lerpSelf(e.vertexNormals[2],0.5),g=e.vertexNormals[3].clone(),g.lerpSelf(e.vertexNormals[0],0.5),w.vertexNormals[2].copy(f),w.vertexNormals[3].copy(g),q.vertexNormals[0].copy(g),q.vertexNormals[1].copy(f)),4===e.vertexColors.length&&(f=e.vertexColors[1].clone(),f.lerpSelf(e.vertexColors[2],0.5),g=e.vertexColors[3].clone(),g.lerpSelf(e.vertexColors[0],0.5),w.vertexColors[2].copy(f),w.vertexColors[3].copy(g),q.vertexColors[0].copy(g),q.vertexColors[1].copy(f)),e=1);E.push(w,q);a.vertices.push(p,l); -f=0;for(g=a.faceVertexUvs.length;f>8&255,i>>16&255,i>>24&255)),d}d.mipmapCount=1;h[2]&131072&&!1!==b&&(d.mipmapCount=Math.max(1,h[7]));d.width=h[4];d.height=h[3];h=h[1]+4;f=d.width;g=d.height;for(i=0;im-1?0:m-1,p=m+1>e-1?e-1:m+1,o=0>l-1?0:l-1,s=l+1>d-1?d-1:l+1,t=[],r=[0,0,h[4*(m*d+l)]/255*b];t.push([-1,0,h[4*(m*d+o)]/255*b]);t.push([-1,-1,h[4*(n*d+o)]/255*b]);t.push([0,-1,h[4*(n*d+l)]/255*b]);t.push([1,-1,h[4*(n*d+s)]/255*b]);t.push([1,0,h[4*(m*d+s)]/255*b]);t.push([1,1,h[4*(p*d+s)]/255*b]);t.push([0,1,h[4*(p*d+l)]/255*b]);t.push([-1,1,h[4*(p*d+o)]/255*b]);n=[];o=t.length;for(p=0;p 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_HEMI_LIGHTS > 0\nuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\nuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\nuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition;", +THREE.ShaderLib={basic:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.fog,THREE.UniformsLib.shadowmap]),vertexShader:[THREE.ShaderChunk.map_pars_vertex,THREE.ShaderChunk.lightmap_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,"void main() {",THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk.color_vertex, +THREE.ShaderChunk.skinbase_vertex,"#ifdef USE_ENVMAP",THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,"#endif",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 diffuse;\nuniform float opacity;",THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment, +THREE.ShaderChunk.lightmap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,"void main() {\ngl_FragColor = vec4( diffuse, opacity );",THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment, +THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},lambert:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{ambient:{type:"c",value:new THREE.Color(16777215)},emissive:{type:"c",value:new THREE.Color(0)},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),vertexShader:["#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\nvarying vec3 vLightBack;\n#endif", +THREE.ShaderChunk.map_pars_vertex,THREE.ShaderChunk.lightmap_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_lambert_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,"void main() {",THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex, +THREE.ShaderChunk.defaultnormal_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_lambert_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\nvarying vec3 vLightBack;\n#endif",THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.lightmap_pars_fragment, +THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,"void main() {\ngl_FragColor = vec4( vec3 ( 1.0 ), opacity );",THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,"#ifdef DOUBLE_SIDED\nif ( gl_FrontFacing )\ngl_FragColor.xyz *= vLightFront;\nelse\ngl_FragColor.xyz *= vLightBack;\n#else\ngl_FragColor.xyz *= vLightFront;\n#endif",THREE.ShaderChunk.lightmap_fragment, +THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},phong:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.bump,THREE.UniformsLib.normalmap,THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{ambient:{type:"c",value:new THREE.Color(16777215)},emissive:{type:"c",value:new THREE.Color(0)},specular:{type:"c", +value:new THREE.Color(1118481)},shininess:{type:"f",value:30},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),vertexShader:["#define PHONG\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;",THREE.ShaderChunk.map_pars_vertex,THREE.ShaderChunk.lightmap_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_phong_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex, +"void main() {",THREE.ShaderChunk.map_vertex,THREE.ShaderChunk.lightmap_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,"vNormal = normalize( transformedNormal );",THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,"vViewPosition = -mvPosition.xyz;",THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex, +THREE.ShaderChunk.lights_phong_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 diffuse;\nuniform float opacity;\nuniform vec3 ambient;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;",THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.lightmap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.lights_phong_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment, +THREE.ShaderChunk.bumpmap_pars_fragment,THREE.ShaderChunk.normalmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,"void main() {\ngl_FragColor = vec4( vec3 ( 1.0 ), opacity );",THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,THREE.ShaderChunk.lights_phong_fragment,THREE.ShaderChunk.lightmap_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment, +THREE.ShaderChunk.fog_fragment,"}"].join("\n")},particle_basic:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.particle,THREE.UniformsLib.shadowmap]),vertexShader:["uniform float size;\nuniform float scale;",THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,"void main() {",THREE.ShaderChunk.color_vertex,"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n#ifdef USE_SIZEATTENUATION\ngl_PointSize = size * ( scale / length( mvPosition.xyz ) );\n#else\ngl_PointSize = size;\n#endif\ngl_Position = projectionMatrix * mvPosition;", +THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 psColor;\nuniform float opacity;",THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.map_particle_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,"void main() {\ngl_FragColor = vec4( psColor, opacity );",THREE.ShaderChunk.map_particle_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.shadowmap_fragment, +THREE.ShaderChunk.fog_fragment,"}"].join("\n")},dashed:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.fog,{scale:{type:"f",value:1},dashSize:{type:"f",value:1},totalSize:{type:"f",value:2}}]),vertexShader:["uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;",THREE.ShaderChunk.color_pars_vertex,"void main() {",THREE.ShaderChunk.color_vertex,"vLineDistance = scale * lineDistance;\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\ngl_Position = projectionMatrix * mvPosition;\n}"].join("\n"), +fragmentShader:["uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;",THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,"void main() {\nif ( mod( vLineDistance, totalSize ) > dashSize ) {\ndiscard;\n}\ngl_FragColor = vec4( diffuse, opacity );",THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},depth:{uniforms:{mNear:{type:"f",value:1},mFar:{type:"f",value:2E3},opacity:{type:"f", +value:1}},vertexShader:"void main() {\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform float mNear;\nuniform float mFar;\nuniform float opacity;\nvoid main() {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat color = 1.0 - smoothstep( mNear, mFar, depth );\ngl_FragColor = vec4( vec3( color ), opacity );\n}"},normal:{uniforms:{opacity:{type:"f",value:1}},vertexShader:["varying vec3 vNormal;",THREE.ShaderChunk.morphtarget_pars_vertex,"void main() {\nvNormal = normalize( normalMatrix * normal );", +THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,"}"].join("\n"),fragmentShader:"uniform float opacity;\nvarying vec3 vNormal;\nvoid main() {\ngl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );\n}"},normalmap:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{enableAO:{type:"i",value:0},enableDiffuse:{type:"i",value:0},enableSpecular:{type:"i",value:0},enableReflection:{type:"i",value:0},enableDisplacement:{type:"i", +value:0},tDisplacement:{type:"t",value:null},tDiffuse:{type:"t",value:null},tCube:{type:"t",value:null},tNormal:{type:"t",value:null},tSpecular:{type:"t",value:null},tAO:{type:"t",value:null},uNormalScale:{type:"v2",value:new THREE.Vector2(1,1)},uDisplacementBias:{type:"f",value:0},uDisplacementScale:{type:"f",value:1},uDiffuseColor:{type:"c",value:new THREE.Color(16777215)},uSpecularColor:{type:"c",value:new THREE.Color(1118481)},uAmbientColor:{type:"c",value:new THREE.Color(16777215)},uShininess:{type:"f", +value:30},uOpacity:{type:"f",value:1},useRefract:{type:"i",value:0},uRefractionRatio:{type:"f",value:0.98},uReflectivity:{type:"f",value:0.5},uOffset:{type:"v2",value:new THREE.Vector2(0,0)},uRepeat:{type:"v2",value:new THREE.Vector2(1,1)},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),fragmentShader:["uniform vec3 uAmbientColor;\nuniform vec3 uDiffuseColor;\nuniform vec3 uSpecularColor;\nuniform float uShininess;\nuniform float uOpacity;\nuniform bool enableDiffuse;\nuniform bool enableSpecular;\nuniform bool enableAO;\nuniform bool enableReflection;\nuniform sampler2D tDiffuse;\nuniform sampler2D tNormal;\nuniform sampler2D tSpecular;\nuniform sampler2D tAO;\nuniform samplerCube tCube;\nuniform vec2 uNormalScale;\nuniform bool useRefract;\nuniform float uRefractionRatio;\nuniform float uReflectivity;\nvarying vec3 vTangent;\nvarying vec3 vBinormal;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nuniform vec3 ambientLightColor;\n#if MAX_DIR_LIGHTS > 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_HEMI_LIGHTS > 0\nuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\nuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\nuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition;", THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,"void main() {\ngl_FragColor = vec4( vec3( 1.0 ), uOpacity );\nvec3 specularTex = vec3( 1.0 );\nvec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;\nnormalTex.xy *= uNormalScale;\nnormalTex = normalize( normalTex );\nif( enableDiffuse ) {\n#ifdef GAMMA_INPUT\nvec4 texelColor = texture2D( tDiffuse, vUv );\ntexelColor.xyz *= texelColor.xyz;\ngl_FragColor = gl_FragColor * texelColor;\n#else\ngl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );\n#endif\n}\nif( enableAO ) {\n#ifdef GAMMA_INPUT\nvec4 aoColor = texture2D( tAO, vUv );\naoColor.xyz *= aoColor.xyz;\ngl_FragColor.xyz = gl_FragColor.xyz * aoColor.xyz;\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * texture2D( tAO, vUv ).xyz;\n#endif\n}\nif( enableSpecular )\nspecularTex = texture2D( tSpecular, vUv ).xyz;\nmat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );\nvec3 finalNormal = tsb * normalTex;\n#ifdef FLIP_SIDED\nfinalNormal = -finalNormal;\n#endif\nvec3 normal = normalize( finalNormal );\nvec3 viewPosition = normalize( vViewPosition );\n#if MAX_POINT_LIGHTS > 0\nvec3 pointDiffuse = vec3( 0.0 );\nvec3 pointSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 pointVector = lPosition.xyz + vViewPosition.xyz;\nfloat pointDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\npointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );\npointVector = normalize( pointVector );\n#ifdef WRAP_AROUND\nfloat pointDiffuseWeightFull = max( dot( normal, pointVector ), 0.0 );\nfloat pointDiffuseWeightHalf = max( 0.5 * dot( normal, pointVector ) + 0.5, 0.0 );\nvec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n#else\nfloat pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );\n#endif\npointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;\nvec3 pointHalfVector = normalize( pointVector + viewPosition );\nfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\nfloat pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( pointVector, pointHalfVector ), 5.0 );\npointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;\n#else\npointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;\n#endif\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nvec3 spotDiffuse = vec3( 0.0 );\nvec3 spotSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 spotVector = lPosition.xyz + vViewPosition.xyz;\nfloat spotDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nspotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );\nspotVector = normalize( spotVector );\nfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\nif ( spotEffect > spotLightAngleCos[ i ] ) {\nspotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );\n#ifdef WRAP_AROUND\nfloat spotDiffuseWeightFull = max( dot( normal, spotVector ), 0.0 );\nfloat spotDiffuseWeightHalf = max( 0.5 * dot( normal, spotVector ) + 0.5, 0.0 );\nvec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n#else\nfloat spotDiffuseWeight = max( dot( normal, spotVector ), 0.0 );\n#endif\nspotDiffuse += spotDistance * spotLightColor[ i ] * uDiffuseColor * spotDiffuseWeight * spotEffect;\nvec3 spotHalfVector = normalize( spotVector + viewPosition );\nfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\nfloat spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( spotVector, spotHalfVector ), 5.0 );\nspotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;\n#else\nspotSpecular += spotDistance * spotLightColor[ i ] * uSpecularColor * spotSpecularWeight * spotDiffuseWeight * spotEffect;\n#endif\n}\n}\n#endif\n#if MAX_DIR_LIGHTS > 0\nvec3 dirDiffuse = vec3( 0.0 );\nvec3 dirSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\n#ifdef WRAP_AROUND\nfloat directionalLightWeightingFull = max( dot( normal, dirVector ), 0.0 );\nfloat directionalLightWeightingHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );\nvec3 dirDiffuseWeight = mix( vec3( directionalLightWeightingFull ), vec3( directionalLightWeightingHalf ), wrapRGB );\n#else\nfloat dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );\n#endif\ndirDiffuse += directionalLightColor[ i ] * uDiffuseColor * dirDiffuseWeight;\nvec3 dirHalfVector = normalize( dirVector + viewPosition );\nfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\nfloat dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );\ndirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n#else\ndirSpecular += directionalLightColor[ i ] * uSpecularColor * dirSpecularWeight * dirDiffuseWeight;\n#endif\n}\n#endif\n#if MAX_HEMI_LIGHTS > 0\nvec3 hemiDiffuse = vec3( 0.0 );\nvec3 hemiSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );\nvec3 lVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, lVector );\nfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\nvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\nhemiDiffuse += uDiffuseColor * hemiColor;\nvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\nfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\nfloat hemiSpecularWeightSky = specularTex.r * max( pow( hemiDotNormalHalfSky, uShininess ), 0.0 );\nvec3 lVectorGround = -lVector;\nvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\nfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\nfloat hemiSpecularWeightGround = specularTex.r * max( pow( hemiDotNormalHalfGround, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat dotProductGround = dot( normal, lVectorGround );\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlickSky = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );\nvec3 schlickGround = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );\nhemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n#else\nhemiSpecular += uSpecularColor * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;\n#endif\n}\n#endif\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n#if MAX_DIR_LIGHTS > 0\ntotalDiffuse += dirDiffuse;\ntotalSpecular += dirSpecular;\n#endif\n#if MAX_HEMI_LIGHTS > 0\ntotalDiffuse += hemiDiffuse;\ntotalSpecular += hemiSpecular;\n#endif\n#if MAX_POINT_LIGHTS > 0\ntotalDiffuse += pointDiffuse;\ntotalSpecular += pointSpecular;\n#endif\n#if MAX_SPOT_LIGHTS > 0\ntotalDiffuse += spotDiffuse;\ntotalSpecular += spotSpecular;\n#endif\n#ifdef METAL\ngl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor ) + totalSpecular;\n#endif\nif ( enableReflection ) {\nvec3 vReflect;\nvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\nif ( useRefract ) {\nvReflect = refract( cameraToVertex, normal, uRefractionRatio );\n} else {\nvReflect = reflect( cameraToVertex, normal );\n}\nvec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );\n#ifdef GAMMA_INPUT\ncubeColor.xyz *= cubeColor.xyz;\n#endif\ngl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * uReflectivity );\n}", THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n"),vertexShader:["attribute vec4 tangent;\nuniform vec2 uOffset;\nuniform vec2 uRepeat;\nuniform bool enableDisplacement;\n#ifdef VERTEX_TEXTURES\nuniform sampler2D tDisplacement;\nuniform float uDisplacementScale;\nuniform float uDisplacementBias;\n#endif\nvarying vec3 vTangent;\nvarying vec3 vBinormal;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition;", THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,"#ifdef USE_SKINNING\nvNormal = normalize( normalMatrix * skinnedNormal.xyz );\nvec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );\nvTangent = normalize( normalMatrix * skinnedTangent.xyz );\n#else\nvNormal = normalize( normalMatrix * normal );\nvTangent = normalize( normalMatrix * tangent.xyz );\n#endif\nvBinormal = normalize( cross( vNormal, vTangent ) * tangent.w );\nvUv = uv * uRepeat + uOffset;\nvec3 displacedPosition;\n#ifdef VERTEX_TEXTURES\nif ( enableDisplacement ) {\nvec3 dv = texture2D( tDisplacement, uv ).xyz;\nfloat df = uDisplacementScale * dv.x + uDisplacementBias;\ndisplacedPosition = position + normalize( normal ) * df;\n} else {\n#ifdef USE_SKINNING\nvec4 skinVertex = vec4( position, 1.0 );\nvec4 skinned = boneMatX * skinVertex * skinWeight.x;\nskinned \t += boneMatY * skinVertex * skinWeight.y;\ndisplacedPosition = skinned.xyz;\n#else\ndisplacedPosition = position;\n#endif\n}\n#else\n#ifdef USE_SKINNING\nvec4 skinVertex = vec4( position, 1.0 );\nvec4 skinned = boneMatX * skinVertex * skinWeight.x;\nskinned \t += boneMatY * skinVertex * skinWeight.y;\ndisplacedPosition = skinned.xyz;\n#else\ndisplacedPosition = position;\n#endif\n#endif\nvec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );\nvec4 worldPosition = modelMatrix * vec4( displacedPosition, 1.0 );\ngl_Position = projectionMatrix * mvPosition;\nvWorldPosition = worldPosition.xyz;\nvViewPosition = -mvPosition.xyz;\n#ifdef USE_SHADOWMAP\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n}\n#endif\n}"].join("\n")}, -cube:{uniforms:{tCube:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:"varying vec3 vWorldPosition;\nvoid main() {\nvec4 worldPosition = modelMatrix * vec4( position, 1.0 );\nvWorldPosition = worldPosition.xyz;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\nvoid main() {\ngl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n}"}}}; -THREE.FontUtils={faces:{},face:"helvetiker",weight:"normal",style:"normal",size:150,divisions:10,getFace:function(){return this.faces[this.face][this.weight][this.style]},loadFace:function(a){var b=a.familyName.toLowerCase();this.faces[b]=this.faces[b]||{};this.faces[b][a.cssFontWeight]=this.faces[b][a.cssFontWeight]||{};this.faces[b][a.cssFontWeight][a.cssFontStyle]=a;return this.faces[b][a.cssFontWeight][a.cssFontStyle]=a},drawText:function(a){for(var b=this.getFace(),c=this.size/b.resolution,d= -0,e=String(a).split(""),f=e.length,g=[],a=0;al;l++)N.autoScaleCubemaps&&!f?(m=j,s=l,t=c.image[l],x=Ic,t.width<=x&&t.height<=x||(y=Math.max(t.width,t.height),u=Math.floor(t.width*x/y),x=Math.floor(t.height*x/y),y=document.createElement("canvas"),y.width=u,y.height=x,y.getContext("2d").drawImage(t,0,0,t.width,t.height,0,0,u,x),t=y),m[s]=t):j[l]=c.image[l];l=j[0];m=0===(l.width&l.width- +1)&&0===(l.height&l.height-1);s=I(c.format);t=I(c.type);B(k.TEXTURE_CUBE_MAP,c,m);for(l=0;6>l;l++)if(f){x=j[l].mipmaps;y=0;for(E=x.length;y=cc&&console.warn("WebGLRenderer: trying to use "+ +a+" texture units while this GPU supports only "+cc);ga+=1;return a}function F(a,b,c,d){a[b]=c.r*c.r*d;a[b+1]=c.g*c.g*d;a[b+2]=c.b*c.b*d}function z(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function H(a){a!==Sa&&(k.lineWidth(a),Sa=a)}function K(a,b,c){Xa!==a&&(a?k.enable(k.POLYGON_OFFSET_FILL):k.disable(k.POLYGON_OFFSET_FILL),Xa=a);if(a&&(Ra!==b||Aa!==c))k.polygonOffset(b,c),Ra=b,Aa=c}function G(a){for(var a=a.split("\n"),b=0,c=a.length;bb;b++)k.deleteFramebuffer(a.__webglFramebuffer[b]),k.deleteRenderbuffer(a.__webglRenderbuffer[b]);else k.deleteFramebuffer(a.__webglFramebuffer),k.deleteRenderbuffer(a.__webglRenderbuffer);N.info.memory.textures--},P=function(a){a=a.target;a.removeEventListener("dispose",P);pc(a)},pc=function(a){var b=a.program;if(void 0!==b){a.program= +void 0;var c,d,e=!1,a=0;for(c=fa.length;ad.numSupportedMorphTargets?(j.sort(m),j.length=d.numSupportedMorphTargets):j.length>d.numSupportedMorphNormals?j.sort(m):0===j.length&&j.push([0,0]);for(l=0;lva;va++)Ma=U[va],xb[ib]=Ma.x,xb[ib+1]=Ma.y,xb[ib+2]=Ma.z,ib+=3;else for(va=0;3>va;va++)xb[ib]=R.x,xb[ib+1]=R.y,xb[ib+2]=R.z,ib+=3;D=0;for(A=ta.length;Dva;va++)Ma=U[va],xb[ib]=Ma.x,xb[ib+1]=Ma.y,xb[ib+2]=Ma.z,ib+=3;else for(va=0;4>va;va++)xb[ib]=R.x,xb[ib+1]=R.y,xb[ib+2]=R.z,ib+=3;k.bindBuffer(k.ARRAY_BUFFER,C.__webglNormalBuffer);k.bufferData(k.ARRAY_BUFFER,xb,G)}if(Kb&& +Vb&&N){D=0;for(A=sa.length;Dva;va++)Ua=Z[va],lb[Ta]=Ua.x,lb[Ta+1]=Ua.y,Ta+=2;D=0;for(A=ta.length;Dva;va++)Ua=Z[va],lb[Ta]=Ua.x,lb[Ta+1]=Ua.y,Ta+=2;0va;va++)Xa=da[va],sb[Va]=Xa.x,sb[Va+1]=Xa.y,Va+=2;D=0;for(A=ta.length;Dva;va++)Xa=da[va],sb[Va]=Xa.x,sb[Va+1]=Xa.y,Va+=2;0f;f++){a.__webglFramebuffer[f]=k.createFramebuffer();a.__webglRenderbuffer[f]=k.createRenderbuffer();k.texImage2D(k.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=k.TEXTURE_CUBE_MAP_POSITIVE_X+f;k.bindFramebuffer(k.FRAMEBUFFER, +a.__webglFramebuffer[f]);k.framebufferTexture2D(k.FRAMEBUFFER,k.COLOR_ATTACHMENT0,h,g.__webglTexture,0);V(a.__webglRenderbuffer[f],a)}c&&k.generateMipmap(k.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=k.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:k.createRenderbuffer(),k.bindTexture(k.TEXTURE_2D,a.__webglTexture),B(k.TEXTURE_2D,a,c),k.texImage2D(k.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=k.TEXTURE_2D,k.bindFramebuffer(k.FRAMEBUFFER,a.__webglFramebuffer), +k.framebufferTexture2D(k.FRAMEBUFFER,k.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?k.framebufferRenderbuffer(k.FRAMEBUFFER,k.DEPTH_ATTACHMENT,k.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&k.framebufferRenderbuffer(k.FRAMEBUFFER,k.DEPTH_STENCIL_ATTACHMENT,k.RENDERBUFFER,a.__webglRenderbuffer):V(a.__webglRenderbuffer,a),c&&k.generateMipmap(k.TEXTURE_2D);b?k.bindTexture(k.TEXTURE_CUBE_MAP,null):k.bindTexture(k.TEXTURE_2D,null);k.bindRenderbuffer(k.RENDERBUFFER, +null);k.bindFramebuffer(k.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=Kb,a=Ob,d=sb,e=Nb);b!==fb&&(k.bindFramebuffer(k.FRAMEBUFFER,b),k.viewport(d,e,c,a),fb=b);Tb=c;Ub=a};this.shadowMapPlugin=new THREE.ShadowMapPlugin;this.addPrePlugin(this.shadowMapPlugin);this.addPostPlugin(new THREE.SpritePlugin);this.addPostPlugin(new THREE.LensFlarePlugin)};THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: +THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=null}; +THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,addEventListener:THREE.EventDispatcher.prototype.addEventListener,hasEventListener:THREE.EventDispatcher.prototype.hasEventListener,removeEventListener:THREE.EventDispatcher.prototype.removeEventListener,dispatchEvent:THREE.EventDispatcher.prototype.dispatchEvent,clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter; +a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps;a.shareDepthFrom=this.shareDepthFrom;return a},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype);THREE.RenderableVertex=function(){this.positionWorld=new THREE.Vector3;this.positionScreen=new THREE.Vector4;this.visible=!0};THREE.RenderableVertex.prototype.copy=function(a){this.positionWorld.copy(a.positionWorld);this.positionScreen.copy(a.positionScreen)};THREE.RenderableFace3=function(){this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.v3=new THREE.RenderableVertex;this.centroidModel=new THREE.Vector3;this.normalModel=new THREE.Vector3;this.normalModelView=new THREE.Vector3;this.vertexNormalsLength=0;this.vertexNormalsModel=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.vertexNormalsModelView=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.material=this.color=null;this.uvs=[[]];this.z=null};THREE.RenderableFace4=function(){this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.v3=new THREE.RenderableVertex;this.v4=new THREE.RenderableVertex;this.centroidModel=new THREE.Vector3;this.normalModel=new THREE.Vector3;this.normalModelView=new THREE.Vector3;this.vertexNormalsLength=0;this.vertexNormalsModel=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.vertexNormalsModelView=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3]; +this.material=this.color=null;this.uvs=[[]];this.z=null};THREE.RenderableObject=function(){this.z=this.object=null};THREE.RenderableParticle=function(){this.rotation=this.z=this.y=this.x=this.object=null;this.scale=new THREE.Vector2;this.material=null};THREE.RenderableLine=function(){this.z=null;this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.vertexColors=[new THREE.Color,new THREE.Color];this.material=null};THREE.GeometryUtils={merge:function(a,b,c){var d,e,f=a.vertices.length,g=b instanceof THREE.Mesh?b.geometry:b,h=a.vertices,i=g.vertices,j=a.faces,m=g.faces,a=a.faceVertexUvs[0],g=g.faceVertexUvs[0];void 0===c&&(c=0);b instanceof THREE.Mesh&&(b.matrixAutoUpdate&&b.updateMatrix(),d=b.matrix,e=(new THREE.Matrix3).getNormalMatrix(d));for(var b=0,p=i.length;ba?b(c,e-1):j[e]>8&255,i>>16&255,i>>24&255)),d}d.mipmapCount=1;h[2]&131072&&!1!==b&&(d.mipmapCount=Math.max(1,h[7]));d.isCubemap=h[28]&512?!0:!1;d.width=h[4];d.height=h[3];for(var h=h[1]+4,f=d.width,g=d.height,i=d.isCubemap? +6:1,j=0;jp-1?0:p-1,r=p+1>e-1?e-1:p+1,s=0>m-1?0:m-1,n=m+1>d-1?d-1:m+1,q=[],y=[0,0,h[4*(p*d+m)]/255*b];q.push([-1,0,h[4*(p*d+s)]/255*b]);q.push([-1,-1,h[4*(l*d+s)]/255*b]);q.push([0,-1,h[4*(l*d+m)]/255*b]);q.push([1,-1,h[4*(l*d+n)]/255*b]);q.push([1,0,h[4*(p*d+n)]/255*b]);q.push([1,1,h[4*(r*d+n)]/255*b]);q.push([0,1,h[4*(r*d+m)]/255*b]);q.push([-1,1,h[4*(r*d+s)]/255*b]);l=[];s=q.length;for(r=0;re)return null;var f=[],g=[],h=[],i,j,l;if(0=m--){console.log("Warning, unable to triangulate polygon!");break}i=j;e<=i&&(i=0);j=i+1;e<=j&&(j=0);l=j+1;e<=l&&(l=0);var n;a:{n=a;var p=i,o=j,s=l,t=e,r=g,z=void 0,w=void 0,q=void 0,E=void 0,A=void 0, -v=void 0,u=void 0,D=void 0,C=void 0,w=n[r[p]].x,q=n[r[p]].y,E=n[r[o]].x,A=n[r[o]].y,v=n[r[s]].x,u=n[r[s]].y;if(1E-10>(E-w)*(u-q)-(A-q)*(v-w))n=!1;else{for(z=0;zi)g=d+1;else if(0b&&(b=0);1d.length-2?d.length-1:a+1;c[3]=a>d.length-3?d.length-1:a+2;b.x=THREE.Curve.Utils.interpolate(d[c[0]].x,d[c[1]].x,d[c[2]].x,d[c[3]].x,e);b.y=THREE.Curve.Utils.interpolate(d[c[0]].y,d[c[1]].y,d[c[2]].y,d[c[3]].y,e);return b}; +(function(a){var b=function(a){for(var b=a.length,e=0,f=b-1,g=0;ge)return null;var f=[],g=[],h=[],i,j,m;if(0=p--){console.log("Warning, unable to triangulate polygon!");break}i=j;e<=i&&(i=0);j=i+1;e<=j&&(j=0);m=j+1;e<=m&&(m=0);var l;a:{var r=l=void 0,s=void 0,n=void 0,q=void 0,y=void 0,u=void 0,x=void 0,t= +void 0,r=a[g[i]].x,s=a[g[i]].y,n=a[g[j]].x,q=a[g[j]].y,y=a[g[m]].x,u=a[g[m]].y;if(1E-10>(n-r)*(u-s)-(q-s)*(y-r))l=!1;else{var E=void 0,J=void 0,F=void 0,z=void 0,H=void 0,K=void 0,G=void 0,L=void 0,B=void 0,V=void 0,B=L=G=t=x=void 0,E=y-n,J=u-q,F=r-y,z=s-u,H=n-r,K=q-s;for(l=0;li)g=d+1;else if(0b&&(b=0);1d.length-2?d.length-1:a+1;c[3]=a>d.length-3?d.length-1:a+2;b.x=THREE.Curve.Utils.interpolate(d[c[0]].x,d[c[1]].x,d[c[2]].x,d[c[3]].x,e);b.y=THREE.Curve.Utils.interpolate(d[c[0]].y,d[c[1]].y,d[c[2]].y,d[c[3]].y,e);return b}; THREE.EllipseCurve=function(a,b,c,d,e,f,g){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=f;this.aClockwise=g};THREE.EllipseCurve.prototype=Object.create(THREE.Curve.prototype);THREE.EllipseCurve.prototype.getPoint=function(a){var b=this.aEndAngle-this.aStartAngle;this.aClockwise||(a=1-a);b=this.aStartAngle+a*b;a=this.aX+this.xRadius*Math.cos(b);b=this.aY+this.yRadius*Math.sin(b);return new THREE.Vector2(a,b)}; THREE.ArcCurve=function(a,b,c,d,e,f){THREE.EllipseCurve.call(this,a,b,c,c,d,e,f)};THREE.ArcCurve.prototype=Object.create(THREE.EllipseCurve.prototype); THREE.Curve.Utils={tangentQuadraticBezier:function(a,b,c,d){return 2*(1-a)*(c-b)+2*a*(d-c)},tangentCubicBezier:function(a,b,c,d,e){return-3*b*(1-a)*(1-a)+3*c*(1-a)*(1-a)-6*a*c*(1-a)+6*a*d*(1-a)-3*a*a*d+3*a*a*e},tangentSpline:function(a){return 6*a*a-6*a+(3*a*a-4*a+1)+(-6*a*a+6*a)+(3*a*a-2*a)},interpolate:function(a,b,c,d,e){var a=0.5*(c-a),d=0.5*(d-b),f=e*e;return(2*b-2*c+a+d)*e*f+(-3*b+3*c-2*a-d)*f+a*e+b}}; -THREE.Curve.create=function(a,b){a.prototype=Object.create(THREE.Curve.prototype);a.prototype.getPoint=b;return a};THREE.LineCurve3=THREE.Curve.create(function(a,b){this.v1=a;this.v2=b},function(a){var b=new THREE.Vector3;b.sub(this.v2,this.v1);b.multiplyScalar(a);b.addSelf(this.v1);return b}); +THREE.Curve.create=function(a,b){a.prototype=Object.create(THREE.Curve.prototype);a.prototype.getPoint=b;return a};THREE.LineCurve3=THREE.Curve.create(function(a,b){this.v1=a;this.v2=b},function(a){var b=new THREE.Vector3;b.subVectors(this.v2,this.v1);b.multiplyScalar(a);b.add(this.v1);return b}); THREE.QuadraticBezierCurve3=THREE.Curve.create(function(a,b,c){this.v0=a;this.v1=b;this.v2=c},function(a){var b,c;b=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);c=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);a=THREE.Shape.Utils.b2(a,this.v0.z,this.v1.z,this.v2.z);return new THREE.Vector3(b,c,a)}); THREE.CubicBezierCurve3=THREE.Curve.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b,c;b=THREE.Shape.Utils.b3(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);c=THREE.Shape.Utils.b3(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);a=THREE.Shape.Utils.b3(a,this.v0.z,this.v1.z,this.v2.z,this.v3.z);return new THREE.Vector3(b,c,a)}); THREE.SplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[]:a},function(a){var b=new THREE.Vector3,c=[],d=this.points,e,a=(d.length-1)*a;e=Math.floor(a);a-=e;c[0]=0==e?e:e-1;c[1]=e;c[2]=e>d.length-2?d.length-1:e+1;c[3]=e>d.length-3?d.length-1:e+2;e=d[c[0]];var f=d[c[1]],g=d[c[2]],c=d[c[3]];b.x=THREE.Curve.Utils.interpolate(e.x,f.x,g.x,c.x,a);b.y=THREE.Curve.Utils.interpolate(e.y,f.y,g.y,c.y,a);b.z=THREE.Curve.Utils.interpolate(e.z,f.z,g.z,c.z,a);return b}); @@ -559,209 +555,156 @@ THREE.ClosedSplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[] d[c[1]].z,d[c[2]].z,d[c[3]].z,e);return b});THREE.CurvePath=function(){this.curves=[];this.bends=[];this.autoClose=!1};THREE.CurvePath.prototype=Object.create(THREE.Curve.prototype);THREE.CurvePath.prototype.add=function(a){this.curves.push(a)};THREE.CurvePath.prototype.checkConnection=function(){};THREE.CurvePath.prototype.closePath=function(){var a=this.curves[0].getPoint(0),b=this.curves[this.curves.length-1].getPoint(1);a.equals(b)||this.curves.push(new THREE.LineCurve(b,a))}; THREE.CurvePath.prototype.getPoint=function(a){for(var b=a*this.getLength(),c=this.getCurveLengths(),a=0;a=b)return b=c[a]-b,a=this.curves[a],b=1-b/a.getLength(),a.getPointAt(b);a++}return null};THREE.CurvePath.prototype.getLength=function(){var a=this.getCurveLengths();return a[a.length-1]}; THREE.CurvePath.prototype.getCurveLengths=function(){if(this.cacheLengths&&this.cacheLengths.length==this.curves.length)return this.cacheLengths;var a=[],b=0,c,d=this.curves.length;for(c=0;cb?b=h.x:h.xc?c=h.y:h.yd?d=h.z:h.zb?b=h.x:h.xc?c=h.y:h.yd?d=h.z:h.zMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; +THREE.Path.prototype.getPoints=function(a,b){if(this.useSpacedPoints)return console.log("tata"),this.getSpacedPoints(a,b);var a=a||12,c=[],d,e,f,g,h,i,j,m,p,l,r,s,n;d=0;for(e=this.actions.length;dMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; THREE.Path.prototype.toShapes=function(){var a,b,c,d,e=[],f=new THREE.Path;a=0;for(b=this.actions.length;a -h&&(h+=c.length);h%=c.length;0>g&&(g+=j.length);g%=j.length;e=0<=h-1?h-1:c.length-1;f=0<=g-1?g-1:j.length-1;s=[j[g],c[h],c[e]];s=THREE.FontUtils.Triangulate.area(s);t=[j[g],j[f],c[h]];t=THREE.FontUtils.Triangulate.area(t);m+n>s+t&&(h=p,g=l,0>h&&(h+=c.length),h%=c.length,0>g&&(g+=j.length),g%=j.length,e=0<=h-1?h-1:c.length-1,f=0<=g-1?g-1:j.length-1);m=c.slice(0,h);n=c.slice(h);p=j.slice(g);l=j.slice(0,g);f=[j[g],j[f],c[h]];o.push([j[g],c[h],c[e]]);o.push(f);c=m.concat(p).concat(l).concat(n)}return{shape:c, -isolatedPts:o,allpoints:d}},triangulateShape:function(a,b){var c=THREE.Shape.Utils.removeHoles(a,b),d=c.allpoints,e=c.isolatedPts,c=THREE.FontUtils.Triangulate(c.shape,!1),f,g,h,i,j={};f=0;for(g=d.length;fd;d++)i=h[d].x+":"+h[d].y,i=j[i],void 0!==i&&(h[d]=i)}f=0;for(g=e.length;fd;d++)i=h[d].x+":"+h[d].y,i=j[i],void 0!==i&&(h[d]=i)}return c.concat(e)}, +b;a++)f=e[a],THREE.Shape.Utils.isClockWise(f.getPoints())?(g.actions=f.actions,g.curves=f.curves,d.push(g),g=new THREE.Shape):g.holes.push(f)}else{a=0;for(b=e.length;a +h&&(h+=c.length);h%=c.length;0>g&&(g+=j.length);g%=j.length;e=0<=h-1?h-1:c.length-1;f=0<=g-1?g-1:j.length-1;n=[j[g],c[h],c[e]];n=THREE.FontUtils.Triangulate.area(n);q=[j[g],j[f],c[h]];q=THREE.FontUtils.Triangulate.area(q);p+l>n+q&&(h=r,g=m,0>h&&(h+=c.length),h%=c.length,0>g&&(g+=j.length),g%=j.length,e=0<=h-1?h-1:c.length-1,f=0<=g-1?g-1:j.length-1);p=c.slice(0,h);l=c.slice(h);r=j.slice(g);m=j.slice(0,g);f=[j[g],j[f],c[h]];s.push([j[g],c[h],c[e]]);s.push(f);c=p.concat(r).concat(m).concat(l)}return{shape:c, +isolatedPts:s,allpoints:d}},triangulateShape:function(a,b){var c=THREE.Shape.Utils.removeHoles(a,b),d=c.allpoints,e=c.isolatedPts,c=THREE.FontUtils.Triangulate(c.shape,!1),f,g,h,i,j={};f=0;for(g=d.length;fd;d++)i=h[d].x+":"+h[d].y,i=j[i],void 0!==i&&(h[d]=i)}f=0;for(g=e.length;fd;d++)i=h[d].x+":"+h[d].y,i=j[i],void 0!==i&&(h[d]=i)}return c.concat(e)}, isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a*a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a,b)+this.b3p1(a,c)+this.b3p2(a,d)+ -this.b3p3(a,e)}}; -THREE.AnimationHandler=function(){var a=[],b={},c={update:function(b){for(var c=0;ca.hierarchy[c].keys[d].time&& +this.b3p3(a,e)}};THREE.AnimationHandler=function(){var a=[],b={},c={update:function(b){for(var c=0;ca.hierarchy[c].keys[d].time&& (a.hierarchy[c].keys[d].time=0),void 0!==a.hierarchy[c].keys[d].rot&&!(a.hierarchy[c].keys[d].rot instanceof THREE.Quaternion)){var h=a.hierarchy[c].keys[d].rot;a.hierarchy[c].keys[d].rot=new THREE.Quaternion(h[0],h[1],h[2],h[3])}if(a.hierarchy[c].keys.length&&void 0!==a.hierarchy[c].keys[0].morphTargets){h={};for(d=0;dp;p++){c=b[p];g=i.prevKey[c];h=i.nextKey[c];if(h.time<=l){if(jd||1d?0:1;if("pos"===c)if(c=a.position,this.interpolationType===THREE.AnimationHandler.LINEAR)c.x=e[0]+(f[0]-e[0])*d,c.y=e[1]+(f[1]-e[1])*d,c.z=e[2]+ -(f[2]-e[2])*d;else{if(this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)this.points[0]=this.getPrevKeyWith("pos",m,g.index-1).pos,this.points[1]=e,this.points[2]=f,this.points[3]=this.getNextKeyWith("pos",m,h.index+1).pos,d=0.33*d+0.33,e=this.interpolateCatmullRom(this.points,d),c.x=e[0],c.y=e[1],c.z=e[2],this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD&&(d=this.interpolateCatmullRom(this.points,1.01*d), -this.target.set(d[0],d[1],d[2]),this.target.subSelf(c),this.target.y=0,this.target.normalize(),d=Math.atan2(this.target.x,this.target.z),a.rotation.set(0,d,0))}else"rot"===c?THREE.Quaternion.slerp(e,f,a.quaternion,d):"scl"===c&&(c=a.scale,c.x=e[0]+(f[0]-e[0])*d,c.y=e[1]+(f[1]-e[1])*d,c.z=e[2]+(f[2]-e[2])*d)}}}}; +THREE.Animation.prototype.update=function(a){if(!1!==this.isPlaying){var b=["pos","rot","scl"],c,d,e,f,g,h,i,j,m;m=this.currentTime+=a*this.timeScale;j=this.currentTime%=this.data.length;parseInt(Math.min(j*this.data.fps,this.data.length*this.data.fps),10);for(var p=0,l=this.hierarchy.length;pr;r++){c=b[r];g=i.prevKey[c];h=i.nextKey[c];if(h.time<=m){if(jd||1d?0:1;if("pos"===c)if(c=a.position,this.interpolationType===THREE.AnimationHandler.LINEAR)c.x=e[0]+(f[0]-e[0])*d,c.y=e[1]+(f[1]-e[1])*d,c.z=e[2]+ +(f[2]-e[2])*d;else{if(this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)this.points[0]=this.getPrevKeyWith("pos",p,g.index-1).pos,this.points[1]=e,this.points[2]=f,this.points[3]=this.getNextKeyWith("pos",p,h.index+1).pos,d=0.33*d+0.33,e=this.interpolateCatmullRom(this.points,d),c.x=e[0],c.y=e[1],c.z=e[2],this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD&&(d=this.interpolateCatmullRom(this.points,1.01*d), +this.target.set(d[0],d[1],d[2]),this.target.sub(c),this.target.y=0,this.target.normalize(),d=Math.atan2(this.target.x,this.target.z),a.rotation.set(0,d,0))}else"rot"===c?THREE.Quaternion.slerp(e,f,a.quaternion,d):"scl"===c&&(c=a.scale,c.x=e[0]+(f[0]-e[0])*d,c.y=e[1]+(f[1]-e[1])*d,c.z=e[2]+(f[2]-e[2])*d)}}}}; THREE.Animation.prototype.interpolateCatmullRom=function(a,b){var c=[],d=[],e,f,g,h,i,j;e=(a.length-1)*b;f=Math.floor(e);e-=f;c[0]=0===f?f:f-1;c[1]=f;c[2]=f>a.length-2?f:f+1;c[3]=f>a.length-3?f:f+2;f=a[c[0]];h=a[c[1]];i=a[c[2]];j=a[c[3]];c=e*e;g=e*c;d[0]=this.interpolate(f[0],h[0],i[0],j[0],e,c,g);d[1]=this.interpolate(f[1],h[1],i[1],j[1],e,c,g);d[2]=this.interpolate(f[2],h[2],i[2],j[2],e,c,g);return d}; THREE.Animation.prototype.interpolate=function(a,b,c,d,e,f,g){a=0.5*(c-a);d=0.5*(d-b);return(2*(b-c)+a+d)*g+(-3*(b-c)-2*a-d)*f+a*e+b};THREE.Animation.prototype.getNextKeyWith=function(a,b,c){for(var d=this.data.hierarchy[b].keys,c=this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD?c=g?b.interpolate(c,g):b.interpolate(c,c.time)}this.data.hierarchy[a].node.updateMatrix();d.matrixWorldNeedsUpdate=!0}}if(this.JITCompile&&void 0===f[0][e]){this.hierarchy[0].updateMatrixWorld(!0);for(a=0;a=g?b.interpolate(c,g):b.interpolate(c,c.time)}this.data.hierarchy[a].node.updateMatrix();d.matrixWorldNeedsUpdate=!0}}if(this.JITCompile&&void 0===f[0][e]){this.hierarchy[0].updateMatrixWorld(!0);for(a=0;ag?(b=Math.atan2(b.y-a.y,b.x-a.x),a=Math.atan2(c.y-a.y,c.x-a.x),b>a&&(a+=2*Math.PI),c=(b+a)/2,a=-Math.cos(c),c=-Math.sin(c),new THREE.Vector2(a,c)):d.multiplyScalar(g).addSelf(h).subSelf(a).clone()}function e(c,d){var e,f;for(J=c.length;0<=--J;){e=J;f=J-1;0>f&&(f=c.length-1); -for(var g=0,h=n+2*l,g=0;gMath.abs(c-i)?[new THREE.UV(b,1-e),new THREE.UV(d,1-f),new THREE.UV(j,1-g),new THREE.UV(m,1-a)]:[new THREE.UV(c,1-e),new THREE.UV(i,1-f),new THREE.UV(l,1-g),new THREE.UV(n,1-a)]}};THREE.ExtrudeGeometry.__v1=new THREE.Vector2;THREE.ExtrudeGeometry.__v2=new THREE.Vector2;THREE.ExtrudeGeometry.__v3=new THREE.Vector2;THREE.ExtrudeGeometry.__v4=new THREE.Vector2;THREE.ExtrudeGeometry.__v5=new THREE.Vector2; -THREE.ExtrudeGeometry.__v6=new THREE.Vector2;THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);!1===a instanceof Array&&(a=[a]);this.shapebb=a[a.length-1].getBoundingBox();this.addShapeList(a,b);this.computeCentroids();this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;cd?(d=new THREE.Face3(a.index,b.index,c.index,[a.clone(),b.clone(),c.clone()]),d.centroid.addSelf(a).addSelf(b).addSelf(c).divideScalar(3),d.normal=d.centroid.clone().normalize(),i.faces.push(d),d=Math.atan2(d.centroid.z,-d.centroid.x), -i.faceVertexUvs[0].push([h(a.uv,a,d),h(b.uv,b,d),h(c.uv,c,d)])):(d-=1,f(a,g(a,b),g(a,c),d),f(g(a,b),b,g(b,c),d),f(g(a,c),g(b,c),c,d),f(g(a,b),g(b,c),g(a,c),d))}function g(a,b){m[a.index]||(m[a.index]=[]);m[b.index]||(m[b.index]=[]);var c=m[a.index][b.index];void 0===c&&(m[a.index][b.index]=m[b.index][a.index]=c=e((new THREE.Vector3).add(a,b).divideScalar(2)));return c}function h(a,b,c){0>c&&1===a.u&&(a=new THREE.UV(a.u-1,a.v));0===b.x&&0===b.z&&(a=new THREE.UV(c/2/Math.PI+0.5,a.v));return a}THREE.Geometry.call(this); -for(var c=c||1,d=d||0,i=this,j=0,l=a.length;j= -l){for(j=0;3>j;j++){l=[i[j],i[(j+1)%3]];m=!0;for(n=0;nh;h++)void 0===f[g[h]]&&(f[g[h]]=e++,this.vertices.push(a[g[h]])),g[h]=f[g[h]]}for(d=0;dr;r++){q=h[r];o=new THREE.Color;o.setRGB(0,0,0);for(var s=0;s=s&&aC.length&&(z[q]=!0)}for(q in n)if(C=n[q],u=C[0],P=C[1],B=q.split("_"),K=B[0],B=B[1],v=new THREE.Vector3,b(0g?(b=Math.atan2(b.y-a.y,b.x-a.x),a=Math.atan2(c.y-a.y,c.x-a.x),b>a&&(a+=2*Math.PI),c=(b+a)/2,a=-Math.cos(c),c=-Math.sin(c),new THREE.Vector2(a,c)):d.multiplyScalar(g).add(h).sub(a).clone()}function e(c,d){var e,f;for(A=c.length;0<=--A;){e=A;f=A-1;0>f&&(f=c.length-1);for(var g=0,h=r+2*m, +g=0;gMath.abs(c-i)?[new THREE.Vector2(b,1-e),new THREE.Vector2(d,1-f),new THREE.Vector2(j,1-g),new THREE.Vector2(p,1-a)]:[new THREE.Vector2(c,1-e),new THREE.Vector2(i,1-f),new THREE.Vector2(m,1-g),new THREE.Vector2(l,1-a)]}};THREE.ExtrudeGeometry.__v1=new THREE.Vector2;THREE.ExtrudeGeometry.__v2=new THREE.Vector2;THREE.ExtrudeGeometry.__v3=new THREE.Vector2;THREE.ExtrudeGeometry.__v4=new THREE.Vector2; +THREE.ExtrudeGeometry.__v5=new THREE.Vector2;THREE.ExtrudeGeometry.__v6=new THREE.Vector2;THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);!1===a instanceof Array&&(a=[a]);this.shapebb=a[a.length-1].getBoundingBox();this.addShapeList(a,b);this.computeCentroids();this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;cc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+0.5,a.y));return a.clone()}THREE.Geometry.call(this);for(var c=c||1,d=d||0,h=this,i=0,j=a.length;il&&(0.2>a&&(d[0].x+=1),0.2>b&&(d[1].x+=1),0.2>m&&(d[2].x+=1));this.mergeVertices();i=0;for(j=this.vertices.length;i=m){for(j=0;3>j;j++){m=[i[j],i[(j+1)%3]];p=!0;for(l=0;lh;h++)void 0===f[g[h]]&&(f[g[h]]=e++,this.vertices.push(a[g[h]])),g[h]=f[g[h]]}for(d=0;dc.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),this.quaternion.setFromAxisAngle(a,b))}}();THREE.ArrowHelper.prototype.setLength=function(a){this.scale.set(a,a,a)}; +THREE.ArrowHelper.prototype.setColor=function(a){this.line.material.color.setHex(a);this.cone.material.color.setHex(a)};THREE.BoxHelper=function(a){var a=a||1,b=new THREE.Geometry,a=[new THREE.Vector3(a,a,a),new THREE.Vector3(-a,a,a),new THREE.Vector3(-a,-a,a),new THREE.Vector3(a,-a,a),new THREE.Vector3(a,a,-a),new THREE.Vector3(-a,a,-a),new THREE.Vector3(-a,-a,-a),new THREE.Vector3(a,-a,-a)];b.vertices.push(a[0],a[1],a[1],a[2],a[2],a[3],a[3],a[0],a[4],a[5],a[5],a[6],a[6],a[7],a[7],a[4],a[0],a[4],a[1],a[5],a[2],a[6],a[3],a[7]);this.vertices=a;THREE.Line.call(this,b,new THREE.LineBasicMaterial,THREE.LinePieces)}; +THREE.BoxHelper.prototype=Object.create(THREE.Line.prototype); +THREE.BoxHelper.prototype.update=function(a){var b=a.geometry;null===b.boundingBox&&b.computeBoundingBox();var c=b.boundingBox.min,b=b.boundingBox.max,d=this.vertices;d[0].set(b.x,b.y,b.z);d[1].set(c.x,b.y,b.z);d[2].set(c.x,c.y,b.z);d[3].set(b.x,c.y,b.z);d[4].set(b.x,b.y,c.z);d[5].set(c.x,b.y,c.z);d[6].set(c.x,c.y,c.z);d[7].set(b.x,c.y,c.z);this.geometry.computeBoundingSphere();this.geometry.verticesNeedUpdate=!0;this.matrixAutoUpdate=!1;this.matrixWorld=a.matrixWorld};THREE.CameraHelper=function(a){function b(a,b,d){c(a,d);c(b,d)}function c(a,b){d.vertices.push(new THREE.Vector3);d.colors.push(new THREE.Color(b));void 0===f[a]&&(f[a]=[]);f[a].push(d.vertices.length-1)}THREE.Line.call(this);var d=new THREE.Geometry,e=new THREE.LineBasicMaterial({color:16777215,vertexColors:THREE.FaceColors}),f={};b("n1","n2",16755200);b("n2","n4",16755200);b("n4","n3",16755200);b("n3","n1",16755200);b("f1","f2",16755200);b("f2","f4",16755200);b("f4","f3",16755200);b("f3","f1",16755200); +b("n1","f1",16755200);b("n2","f2",16755200);b("n3","f3",16755200);b("n4","f4",16755200);b("p","n1",16711680);b("p","n2",16711680);b("p","n3",16711680);b("p","n4",16711680);b("u1","u2",43775);b("u2","u3",43775);b("u3","u1",43775);b("c","t",16777215);b("p","c",3355443);b("cn1","cn2",3355443);b("cn3","cn4",3355443);b("cf1","cf2",3355443);b("cf3","cf4",3355443);THREE.Line.call(this,d,e,THREE.LinePieces);this.camera=a;this.matrixWorld=a.matrixWorld;this.matrixAutoUpdate=!1;this.pointMap=f;this.update()}; +THREE.CameraHelper.prototype=Object.create(THREE.Line.prototype); +THREE.CameraHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Camera,c=new THREE.Projector;return function(){function d(d,g,h,i){a.set(g,h,i);c.unprojectVector(a,b);d=e.pointMap[d];if(void 0!==d){g=0;for(h=d.length;gd;d++)c.faces[d].materialIndex=4>d?0:1;d=new THREE.MeshBasicMaterial({fog:!1,wireframe:!0});d.color.copy(a.color).multiplyScalar(a.intensity);var e=new THREE.MeshBasicMaterial({fog:!1,wireframe:!0});e.color.copy(a.groundColor).multiplyScalar(a.intensity);this.lightSphere=new THREE.Mesh(c,new THREE.MeshFaceMaterial([d, +e]));this.lightSphere.position=a.position;this.lightSphere.lookAt(new THREE.Vector3);this.add(this.lightSphere)};THREE.HemisphereLightHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.HemisphereLightHelper.prototype.update=function(){this.lightSphere.lookAt(new THREE.Vector3);this.lightSphere.material.materials[0].color.copy(this.light.color).multiplyScalar(this.light.intensity);this.lightSphere.material.materials[1].color.copy(this.light.groundColor).multiplyScalar(this.light.intensity)};THREE.PointLightHelper=function(a,b){THREE.Object3D.call(this);this.matrixAutoUpdate=!1;this.light=a;var c=new THREE.SphereGeometry(b,4,2),d=new THREE.MeshBasicMaterial({fog:!1,wireframe:!0});d.color.copy(this.light.color).multiplyScalar(this.light.intensity);this.lightSphere=new THREE.Mesh(c,d);this.lightSphere.matrixWorld=this.light.matrixWorld;this.lightSphere.matrixAutoUpdate=!1;this.add(this.lightSphere)};THREE.PointLightHelper.prototype=Object.create(THREE.Object3D.prototype); +THREE.PointLightHelper.prototype.update=function(){this.lightSphere.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)};THREE.SpotLightHelper=function(a,b){THREE.Object3D.call(this);this.matrixAutoUpdate=!1;this.light=a;var c=new THREE.SphereGeometry(b,4,2),d=new THREE.MeshBasicMaterial({fog:!1,wireframe:!0});d.color.copy(this.light.color).multiplyScalar(this.light.intensity);this.lightSphere=new THREE.Mesh(c,d);this.lightSphere.matrixWorld=this.light.matrixWorld;this.lightSphere.matrixAutoUpdate=!1;this.add(this.lightSphere);c=new THREE.CylinderGeometry(1E-4,1,1,8,1,!0);c.applyMatrix((new THREE.Matrix4).makeTranslation(0, +-0.5,0));c.applyMatrix((new THREE.Matrix4).makeRotationX(-Math.PI/2));d=new THREE.MeshBasicMaterial({fog:!1,wireframe:!0,opacity:0.3,transparent:!0});d.color.copy(this.light.color).multiplyScalar(this.light.intensity);this.lightCone=new THREE.Mesh(c,d);this.lightCone.position=this.light.position;c=a.distance?a.distance:1E4;d=c*Math.tan(a.angle);this.lightCone.scale.set(d,d,c);this.lightCone.lookAt(this.light.target.position);this.add(this.lightCone)};THREE.SpotLightHelper.prototype=Object.create(THREE.Object3D.prototype); +THREE.SpotLightHelper.prototype.update=function(){var a=this.light.distance?this.light.distance:1E4,b=a*Math.tan(this.light.angle);this.lightCone.scale.set(b,b,a);this.lightCone.lookAt(this.light.target.position);this.lightSphere.material.color.copy(this.light.color).multiplyScalar(this.light.intensity);this.lightCone.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)};THREE.ImmediateRenderObject=function(){THREE.Object3D.call(this);this.render=function(){}};THREE.ImmediateRenderObject.prototype=Object.create(THREE.Object3D.prototype);THREE.LensFlare=function(a,b,c,d,e){THREE.Object3D.call(this);this.lensFlares=[];this.positionScreen=new THREE.Vector3;this.customUpdateCallback=void 0;void 0!==a&&this.add(a,b,c,d,e)};THREE.LensFlare.prototype=Object.create(THREE.Object3D.prototype); +THREE.LensFlare.prototype.add=function(a,b,c,d,e,f){void 0===b&&(b=-1);void 0===c&&(c=0);void 0===f&&(f=1);void 0===e&&(e=new THREE.Color(16777215));void 0===d&&(d=THREE.NormalBlending);c=Math.min(c,Math.max(0,c));this.lensFlares.push({texture:a,size:b,distance:c,x:0,y:0,z:0,scale:1,rotation:1,opacity:f,color:e,blending:d})}; +THREE.LensFlare.prototype.updateLensFlares=function(){var a,b=this.lensFlares.length,c,d=2*-this.positionScreen.x,e=2*-this.positionScreen.y;for(a=0;ah.end&&(h.end=f);c||(c=i)}}for(i in d)h=d[i],this.createAnimation(i,h.start,h.end,a);this.firstAnimation=c}; THREE.MorphBlendMesh.prototype.setAnimationDirectionForward=function(a){if(a=this.animationsMap[a])a.direction=1,a.directionBackwards=!1};THREE.MorphBlendMesh.prototype.setAnimationDirectionBackward=function(a){if(a=this.animationsMap[a])a.direction=-1,a.directionBackwards=!0};THREE.MorphBlendMesh.prototype.setAnimationFPS=function(a,b){var c=this.animationsMap[a];c&&(c.fps=b,c.duration=(c.end-c.start)/c.fps)}; THREE.MorphBlendMesh.prototype.setAnimationDuration=function(a,b){var c=this.animationsMap[a];c&&(c.duration=b,c.fps=(c.end-c.start)/c.duration)};THREE.MorphBlendMesh.prototype.setAnimationWeight=function(a,b){var c=this.animationsMap[a];c&&(c.weight=b)};THREE.MorphBlendMesh.prototype.setAnimationTime=function(a,b){var c=this.animationsMap[a];c&&(c.time=b)};THREE.MorphBlendMesh.prototype.getAnimationTime=function(a){var b=0;if(a=this.animationsMap[a])b=a.time;return b}; THREE.MorphBlendMesh.prototype.getAnimationDuration=function(a){var b=-1;if(a=this.animationsMap[a])b=a.duration;return b};THREE.MorphBlendMesh.prototype.playAnimation=function(a){var b=this.animationsMap[a];b?(b.time=0,b.active=!0):console.warn("animation["+a+"] undefined")};THREE.MorphBlendMesh.prototype.stopAnimation=function(a){if(a=this.animationsMap[a])a.active=!1}; -THREE.MorphBlendMesh.prototype.update=function(a){for(var b=0,c=this.animationsList.length;bd.duration||0>d.time)if(d.direction*=-1,d.time>d.duration&&(d.time=d.duration,d.directionBackwards=!0),0>d.time)d.time=0,d.directionBackwards=!1}else d.time%=d.duration,0>d.time&&(d.time+=d.duration);var f=d.startFrame+THREE.Math.clamp(Math.floor(d.time/e),0,d.length-1),g=d.weight; -f!==d.currentFrame&&(this.morphTargetInfluences[d.lastFrame]=0,this.morphTargetInfluences[d.currentFrame]=1*g,this.morphTargetInfluences[f]=0,d.lastFrame=d.currentFrame,d.currentFrame=f);e=d.time%e/e;d.directionBackwards&&(e=1-e);this.morphTargetInfluences[d.currentFrame]=e*g;this.morphTargetInfluences[d.lastFrame]=(1-e)*g}}}; -THREE.LensFlarePlugin=function(){function a(a){var c=b.createProgram(),d=b.createShader(b.FRAGMENT_SHADER),e=b.createShader(b.VERTEX_SHADER);b.shaderSource(d,a.fragmentShader);b.shaderSource(e,a.vertexShader);b.compileShader(d);b.compileShader(e);b.attachShader(c,d);b.attachShader(c,e);b.linkProgram(c);return c}var b,c,d,e,f,g,h,i,j,l,m,n,p;this.init=function(o){b=o.context;c=o;d=new Float32Array(16);e=new Uint16Array(6);o=0;d[o++]=-1;d[o++]=-1;d[o++]=0;d[o++]=0;d[o++]=1;d[o++]=-1;d[o++]=1;d[o++]= -0;d[o++]=1;d[o++]=1;d[o++]=1;d[o++]=1;d[o++]=-1;d[o++]=1;d[o++]=0;d[o++]=1;o=0;e[o++]=0;e[o++]=1;e[o++]=2;e[o++]=0;e[o++]=2;e[o++]=3;f=b.createBuffer();g=b.createBuffer();b.bindBuffer(b.ARRAY_BUFFER,f);b.bufferData(b.ARRAY_BUFFER,d,b.STATIC_DRAW);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,g);b.bufferData(b.ELEMENT_ARRAY_BUFFER,e,b.STATIC_DRAW);h=b.createTexture();i=b.createTexture();b.bindTexture(b.TEXTURE_2D,h);b.texImage2D(b.TEXTURE_2D,0,b.RGB,16,16,0,b.RGB,b.UNSIGNED_BYTE,null);b.texParameteri(b.TEXTURE_2D, -b.TEXTURE_WRAP_S,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.NEAREST);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.NEAREST);b.bindTexture(b.TEXTURE_2D,i);b.texImage2D(b.TEXTURE_2D,0,b.RGBA,16,16,0,b.RGBA,b.UNSIGNED_BYTE,null);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.NEAREST); -b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.NEAREST);0>=b.getParameter(b.MAX_VERTEX_TEXTURE_IMAGE_UNITS)?(j=!1,l=a(THREE.ShaderFlares.lensFlare)):(j=!0,l=a(THREE.ShaderFlares.lensFlareVertexTexture));m={};n={};m.vertex=b.getAttribLocation(l,"position");m.uv=b.getAttribLocation(l,"uv");n.renderType=b.getUniformLocation(l,"renderType");n.map=b.getUniformLocation(l,"map");n.occlusionMap=b.getUniformLocation(l,"occlusionMap");n.opacity=b.getUniformLocation(l,"opacity");n.color=b.getUniformLocation(l, -"color");n.scale=b.getUniformLocation(l,"scale");n.rotation=b.getUniformLocation(l,"rotation");n.screenPosition=b.getUniformLocation(l,"screenPosition");p=!1};this.render=function(a,d,e,r){var a=a.__webglFlares,z=a.length;if(z){var w=new THREE.Vector3,q=r/e,E=0.5*e,A=0.5*r,v=16/r,u=new THREE.Vector2(v*q,v),D=new THREE.Vector3(1,1,0),C=new THREE.Vector2(1,1),G=n,v=m;b.useProgram(l);p||(b.enableVertexAttribArray(m.vertex),b.enableVertexAttribArray(m.uv),p=!0);b.uniform1i(G.occlusionMap,0);b.uniform1i(G.map, -1);b.bindBuffer(b.ARRAY_BUFFER,f);b.vertexAttribPointer(v.vertex,2,b.FLOAT,!1,16,0);b.vertexAttribPointer(v.uv,2,b.FLOAT,!1,16,8);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,g);b.disable(b.CULL_FACE);b.depthMask(!1);var P,B,K,H,I;for(P=0;Pv;v++)w[v]=new THREE.Vector3,r[v]=new THREE.Vector3;w=q.shadowCascadeNearZ[z];q=q.shadowCascadeFarZ[z];r[0].set(-1,-1,w);r[1].set(1,-1,w);r[2].set(-1, -1,w);r[3].set(1,1,w);r[4].set(-1,-1,q);r[5].set(1,-1,q);r[6].set(-1,1,q);r[7].set(1,1,q);A.originalCamera=m;r=new THREE.Gyroscope;r.position=o.shadowCascadeOffset;r.add(A);r.add(A.target);m.add(r);o.shadowCascadeArray[t]=A;console.log("Created virtualLight",A)}z=o;w=t;q=z.shadowCascadeArray[w];q.position.copy(z.position);q.target.position.copy(z.target.position);q.lookAt(q.target);q.shadowCameraVisible=z.shadowCameraVisible;q.shadowDarkness=z.shadowDarkness;q.shadowBias=z.shadowCascadeBias[w];r=z.shadowCascadeNearZ[w]; -z=z.shadowCascadeFarZ[w];q=q.pointsFrustum;q[0].z=r;q[1].z=r;q[2].z=r;q[3].z=r;q[4].z=z;q[5].z=z;q[6].z=z;q[7].z=z;E[s]=A;s++}else E[s]=o,s++;n=0;for(p=E.length;nz;z++)if(w=q[z],w.copy(r[z]),THREE.ShadowMapPlugin.__projector.unprojectVector(w,t),s.matrixWorldInverse.multiplyVector3(w),w.xj.x&&(j.x=w.x),w.yj.y&&(j.y=w.y),w.zj.z)j.z=w.z;s.left=i.x;s.right= -j.x;s.top=j.y;s.bottom=i.y;s.updateProjectionMatrix()}s=o.shadowMap;r=o.shadowMatrix;t=o.shadowCamera;t.position.copy(o.matrixWorld.getPosition());t.lookAt(o.target.matrixWorld.getPosition());t.updateMatrixWorld();t.matrixWorldInverse.getInverse(t.matrixWorld);o.cameraHelper&&(o.cameraHelper.visible=o.shadowCameraVisible);o.shadowCameraVisible&&o.cameraHelper.update();r.set(0.5,0,0,0.5,0,0.5,0,0.5,0,0,0.5,0.5,0,0,0,1);r.multiplySelf(t.projectionMatrix);r.multiplySelf(t.matrixWorldInverse);t._viewMatrixArray|| -(t._viewMatrixArray=new Float32Array(16));t._projectionMatrixArray||(t._projectionMatrixArray=new Float32Array(16));t.matrixWorldInverse.flattenToArray(t._viewMatrixArray);t.projectionMatrix.flattenToArray(t._projectionMatrixArray);h.multiply(t.projectionMatrix,t.matrixWorldInverse);g.setFromMatrix(h);b.setRenderTarget(s);b.clear();q=l.__webglObjects;o=0;for(s=q.length;o 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"}}; +THREE.MorphBlendMesh.prototype.update=function(a){for(var b=0,c=this.animationsList.length;bd.duration||0>d.time)d.direction*=-1,d.time>d.duration&&(d.time=d.duration,d.directionBackwards=!0),0>d.time&&(d.time=0,d.directionBackwards=!1)}else d.time%=d.duration,0>d.time&&(d.time+=d.duration);var f=d.startFrame+THREE.Math.clamp(Math.floor(d.time/e),0,d.length-1),g=d.weight; +f!==d.currentFrame&&(this.morphTargetInfluences[d.lastFrame]=0,this.morphTargetInfluences[d.currentFrame]=1*g,this.morphTargetInfluences[f]=0,d.lastFrame=d.currentFrame,d.currentFrame=f);e=d.time%e/e;d.directionBackwards&&(e=1-e);this.morphTargetInfluences[d.currentFrame]=e*g;this.morphTargetInfluences[d.lastFrame]=(1-e)*g}}};THREE.LensFlarePlugin=function(){function a(a,c){var d=b.createProgram(),e=b.createShader(b.FRAGMENT_SHADER),f=b.createShader(b.VERTEX_SHADER),g="precision "+c+" float;\n";b.shaderSource(e,g+a.fragmentShader);b.shaderSource(f,g+a.vertexShader);b.compileShader(e);b.compileShader(f);b.attachShader(d,e);b.attachShader(d,f);b.linkProgram(d);return d}var b,c,d,e,f,g,h,i,j,m,p,l,r;this.init=function(s){b=s.context;c=s;d=s.getPrecision();e=new Float32Array(16);f=new Uint16Array(6);s=0;e[s++]=-1;e[s++]=-1; +e[s++]=0;e[s++]=0;e[s++]=1;e[s++]=-1;e[s++]=1;e[s++]=0;e[s++]=1;e[s++]=1;e[s++]=1;e[s++]=1;e[s++]=-1;e[s++]=1;e[s++]=0;e[s++]=1;s=0;f[s++]=0;f[s++]=1;f[s++]=2;f[s++]=0;f[s++]=2;f[s++]=3;g=b.createBuffer();h=b.createBuffer();b.bindBuffer(b.ARRAY_BUFFER,g);b.bufferData(b.ARRAY_BUFFER,e,b.STATIC_DRAW);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,h);b.bufferData(b.ELEMENT_ARRAY_BUFFER,f,b.STATIC_DRAW);i=b.createTexture();j=b.createTexture();b.bindTexture(b.TEXTURE_2D,i);b.texImage2D(b.TEXTURE_2D,0,b.RGB,16,16, +0,b.RGB,b.UNSIGNED_BYTE,null);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.NEAREST);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.NEAREST);b.bindTexture(b.TEXTURE_2D,j);b.texImage2D(b.TEXTURE_2D,0,b.RGBA,16,16,0,b.RGBA,b.UNSIGNED_BYTE,null);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.CLAMP_TO_EDGE); +b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.NEAREST);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.NEAREST);0>=b.getParameter(b.MAX_VERTEX_TEXTURE_IMAGE_UNITS)?(m=!1,p=a(THREE.ShaderFlares.lensFlare,d)):(m=!0,p=a(THREE.ShaderFlares.lensFlareVertexTexture,d));l={};r={};l.vertex=b.getAttribLocation(p,"position");l.uv=b.getAttribLocation(p,"uv");r.renderType=b.getUniformLocation(p,"renderType");r.map=b.getUniformLocation(p,"map");r.occlusionMap=b.getUniformLocation(p,"occlusionMap");r.opacity= +b.getUniformLocation(p,"opacity");r.color=b.getUniformLocation(p,"color");r.scale=b.getUniformLocation(p,"scale");r.rotation=b.getUniformLocation(p,"rotation");r.screenPosition=b.getUniformLocation(p,"screenPosition")};this.render=function(a,d,e,f){var a=a.__webglFlares,u=a.length;if(u){var x=new THREE.Vector3,t=f/e,E=0.5*e,J=0.5*f,F=16/f,z=new THREE.Vector2(F*t,F),H=new THREE.Vector3(1,1,0),K=new THREE.Vector2(1,1),G=r,F=l;b.useProgram(p);b.enableVertexAttribArray(l.vertex);b.enableVertexAttribArray(l.uv); +b.uniform1i(G.occlusionMap,0);b.uniform1i(G.map,1);b.bindBuffer(b.ARRAY_BUFFER,g);b.vertexAttribPointer(F.vertex,2,b.FLOAT,!1,16,0);b.vertexAttribPointer(F.uv,2,b.FLOAT,!1,16,8);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,h);b.disable(b.CULL_FACE);b.depthMask(!1);var L,B,V,C,I;for(L=0;Lz;z++)t[z]=new THREE.Vector3,u[z]=new THREE.Vector3;t=E.shadowCascadeNearZ[x];E=E.shadowCascadeFarZ[x];u[0].set(-1,-1,t);u[1].set(1,-1,t);u[2].set(-1, +1,t);u[3].set(1,1,t);u[4].set(-1,-1,E);u[5].set(1,-1,E);u[6].set(-1,1,E);u[7].set(1,1,E);F.originalCamera=l;u=new THREE.Gyroscope;u.position=n.shadowCascadeOffset;u.add(F);u.add(F.target);l.add(u);n.shadowCascadeArray[y]=F;console.log("Created virtualLight",F)}x=n;t=y;E=x.shadowCascadeArray[t];E.position.copy(x.position);E.target.position.copy(x.target.position);E.lookAt(E.target);E.shadowCameraVisible=x.shadowCameraVisible;E.shadowDarkness=x.shadowDarkness;E.shadowBias=x.shadowCascadeBias[t];u=x.shadowCascadeNearZ[t]; +x=x.shadowCascadeFarZ[t];E=E.pointsFrustum;E[0].z=u;E[1].z=u;E[2].z=u;E[3].z=u;E[4].z=x;E[5].z=x;E[6].z=x;E[7].z=x;J[q]=F;q++}else J[q]=n,q++;r=0;for(s=J.length;rx;x++)t=E[x],t.copy(u[x]),THREE.ShadowMapPlugin.__projector.unprojectVector(t,y),t.applyMatrix4(q.matrixWorldInverse),t.xj.x&&(j.x=t.x),t.yj.y&&(j.y=t.y),t.zj.z&& +(j.z=t.z);q.left=i.x;q.right=j.x;q.top=j.y;q.bottom=i.y;q.updateProjectionMatrix()}q=n.shadowMap;u=n.shadowMatrix;y=n.shadowCamera;y.position.getPositionFromMatrix(n.matrixWorld);m.getPositionFromMatrix(n.target.matrixWorld);y.lookAt(m);y.updateMatrixWorld();y.matrixWorldInverse.getInverse(y.matrixWorld);n.cameraHelper&&(n.cameraHelper.visible=n.shadowCameraVisible);n.shadowCameraVisible&&n.cameraHelper.update();u.set(0.5,0,0,0.5,0,0.5,0,0.5,0,0,0.5,0.5,0,0,0,1);u.multiply(y.projectionMatrix);u.multiply(y.matrixWorldInverse); +h.multiplyMatrices(y.projectionMatrix,y.matrixWorldInverse);g.setFromMatrix(h);b.setRenderTarget(q);b.clear();E=p.__webglObjects;n=0;for(q=E.length;n 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"}}; diff --git a/src/addons/Display/qtDisplay.py b/src/addons/Display/qtDisplay.py index 3b38bd4fb..dbff052a5 100644 --- a/src/addons/Display/qtDisplay.py +++ b/src/addons/Display/qtDisplay.py @@ -38,7 +38,6 @@ class qtBaseViewer(QtOpenGL.QGLWidget): ''' The base Qt Widget for an OCC viewer ''' def __init__(self, parent = None): - # QtGui.QWidget.__init__(self,parent) QtOpenGL.QGLWidget.__init__(self,parent) self._display = None self._inited = False @@ -56,12 +55,6 @@ def resizeEvent(self, event): if self._inited: self._display.OnResize() - # def initializeGL(self): - # import ipdb; ipdb.set_trace() - # - # def paintGL(self): - # import ipdb; ipdb.set_trace() - def paintEngine(self): return None @@ -100,8 +93,6 @@ def set_shade_mode(): ord('Q'): self._display.SetModeQuickHLR, ord('E'): self._display.SetModeExactHLR, ord('F'): self._display.FitAll, - #ord('F'): self._display.ExportToImage("essai.BMP"), - #ord('F'): self._display.SetBackgroundImage("carrelage1.gif"), ord('G'): self._display.SetSelectionMode } diff --git a/src/addons/Display/wxDisplay.py b/src/addons/Display/wxDisplay.py index 8c5d2e3d1..1e9ece6a1 100644 --- a/src/addons/Display/wxDisplay.py +++ b/src/addons/Display/wxDisplay.py @@ -84,26 +84,6 @@ def OnMotion(self,event): pass def OnKeyDown(self,event): pass - -class wxViewer2d(wxBaseViewer): - def __init__(self, *kargs): - wxBaseViewer.__init__(self, *kargs) - print "wxViewer2d inited" - - def InitDriver(self): - """ - This method is called after __init__ in the wxBaseViewer class - """ - self._display = OCCViewer.Viewer2d(self.GetHandle()) - self._display.Create() - self._inited = True - - def OnMotion(self, evt): - print "Motion!!" - pt = evt.GetPosition() - print pt.x, pt.y - self._display.MoveTo(pt.x,pt.y) - class wxNISViewer3d(wxBaseViewer): def __init__(self, *kargs): @@ -215,7 +195,7 @@ def OnPaint(self, event): self._display.Repaint() def ZoomAll(self, evt): - self._display.Zoom_FitAll() + self._display.FitAll() def Repaint(self, evt): if self._inited: diff --git a/src/addons/KBE/__init__.py b/src/addons/KBE/__init__.py index 13acd6762..e69de29bb 100644 --- a/src/addons/KBE/__init__.py +++ b/src/addons/KBE/__init__.py @@ -1,4 +0,0 @@ -#from vertex import Vertex -#from edge import Edge -#from face import Face -#from solid import Shell, Solid \ No newline at end of file diff --git a/src/addons/KBE/base.py b/src/addons/KBE/base.py index b2c250fdc..d32b8bc3f 100644 --- a/src/addons/KBE/base.py +++ b/src/addons/KBE/base.py @@ -209,5 +209,3 @@ def oriented_bbox(self): [ has an implementation at hb-robo-code ] """ pass - - diff --git a/src/addons/KBE/edge.py b/src/addons/KBE/edge.py index 3e1412ce0..9371994c2 100644 --- a/src/addons/KBE/edge.py +++ b/src/addons/KBE/edge.py @@ -1,17 +1,9 @@ -from OCC.BRep import BRep_Tool from OCC.BRepAdaptor import BRepAdaptor_Curve, BRepAdaptor_HCurve from OCC.GCPnts import GCPnts_UniformAbscissa from OCC.Geom import Geom_OffsetCurve, Geom_TrimmedCurve -from OCC.KBE.base import KbeObject from OCC.TopExp import TopExp from OCC.TopoDS import TopoDS_Edge, TopoDS_Vertex, TopoDS_Face from OCC.gp import * -# high-level -from OCC.Utils.Common import vertex2pnt, minimum_distance -from OCC.Utils.Construct import make_edge, fix_continuity -from OCC.Utils.Context import assert_isdone -from OCC.KBE.vertex import Vertex -from OCC.KBE.types_lut import geom_lut from OCC.GeomLProp import GeomLProp_CurveTool from OCC.BRepLProp import BRepLProp_CLProps from OCC.GeomLib import GeomLib @@ -20,6 +12,14 @@ from OCC.ShapeAnalysis import ShapeAnalysis_Edge from OCC.BRep import * +# high-level +from OCC.Utils.Common import vertex2pnt, minimum_distance +from OCC.Utils.Construct import make_edge, fix_continuity +from OCC.Utils.Context import assert_isdone +from OCC.KBE.vertex import Vertex +from OCC.KBE.types_lut import geom_lut +from OCC.KBE.base import KbeObject + class IntersectCurve(object): def __init__(self, instance): self.instance = instance @@ -38,13 +38,9 @@ def intersect(self, other, disp, tolerance=1e-2): pnts.append(face_curve_intersect.Pnt()) return pnts - - - class DiffGeomCurve(object): def __init__(self, instance): self.instance = instance - #self._local_props = BRepLProp_CLProps(self.instance.adaptor, self.instance.degree(), self.instance.tolerance) self._local_props = BRepLProp_CLProps(self.instance.adaptor, 2, self.instance.tolerance) # initialize with random parameter: 0 @@ -65,7 +61,7 @@ def radius(self, u): return pnt def curvature(self, u): - # UGLYYYYYYYYYYYY + # ugly self._curvature.SetParameter(u) return self._curvature.Curvature() @@ -94,24 +90,6 @@ def normal(self, u): self._curvature.Normal(ddd) return ddd except: -# gp_Vec d1u, d2u; - -# Handle_Geom_Curve aCurv=aCertainCurve; -# -# Standard_Real u=aCertainValue; -# -# // get 1st and 2nd derivative in u -# -# aCurv->D2(u, aPnt, d1u, d2u); -# -# Standard_Real nu_dot = d1u.Dot(d2u)/d1u.Magnitude(); -# -# gp_Vec t_vec = d1u.Divided(d1u.Magnitude()); -# -# // compute the main normal (not the bi normal) -# -# gp_Vec mainn = d2u-(nu_dot*t_vec); - raise ValueError('no normal was found') def derivative(self, u, n): @@ -131,12 +109,9 @@ def derivative(self, u, n): def points_from_tangential_deflection(self): pass - - #=============================================================================== # Curve.Construct #=============================================================================== - class ConstructFromCurve(): def __init__(self, instance): self.instance = instance @@ -189,9 +164,6 @@ def __init__(self, edge): # GeomLProp object self._curvature = None - #self._local_properties() - - # some aliasing of useful methods def is_closed(self): return self.adaptor.IsClosed() @@ -220,7 +192,6 @@ def nb_knots(self): def nb_poles(self): return self.adaptor.NbPoles() - @property def curve(self): if self._curve is not None and not self.is_dirty: @@ -321,10 +292,6 @@ def trim(self, lbound, ubound, periodic=False): @param lbound: @param ubound: ''' -# if self.is_periodic: -# pass -# else: -# warnings.warn('the wire to be trimmed is not closed, hence cannot be made periodic') a,b = sorted([lbound,ubound]) tr = Geom_TrimmedCurve(self.adaptor.Curve().Curve(), a,b).GetHandle() return Edge(make_edge(tr)) @@ -344,7 +311,6 @@ def extend_by_point(self, pnt, degree=3, beginning=True): #=============================================================================== # Curve. #=============================================================================== - def closest(self, other): return minimum_distance(self.brep, other) @@ -392,7 +358,8 @@ def divide_by_number_of_points(self, n_pts, lbound=None, ubound=None): try: npts = GCPnts_UniformAbscissa(self.adaptor, n_pts, _lbound, _ubound) except: - import ipdb; ipdb.set_trace() + #import ipdb; ipdb.set_trace() + print "Warning : GCPnts_UniformAbscissa failed" if npts.IsDone(): tmp = [] for i in xrange(1,npts.NbPoints()+1): @@ -427,19 +394,6 @@ def greville_points(self): '''descriptor setting or getting the coordinate of a control point at indx''' raise NotImplementedError - -# @property -# def periodic(self): -# return self.adaptor.IsPeriodic() -# -# @periodic.setter -# def periodic(self, _bool): -# _bool = bool(_bool) -# if self.is_closed: -# self.adaptor.BSpline() -# else: -# raise warnings.warn('cannot set periodicity on a non-closed edge') - def control_point(self, indx, pt=None): '''gets or sets the coordinate of the control point ''' @@ -454,15 +408,6 @@ def __eq__(self, other): def __ne__(self, other): return not(self.__eq__(other)) -# def __cmp__(self, other): -# return self.__eq__(other) - -# def __contains__(self, item): -# print 'in list?' -# import ipdb; ipdb.set_trace() -# return 0 -# -# def first_vertex(self): # TODO: should return Vertex, not TopoDS_Vertex return TopExp.FirstVertex(self) @@ -583,8 +528,6 @@ def show(self, poles=False, vertices=False, knots=False): http://www.opencascade.org/org/forum/thread_1125/ ''' show = super(Edge, self).show() - #if not poles and not vertices and not knots: - # show() def update(self, context): '''updates the graphic presentation when called diff --git a/src/addons/KBE/face.py b/src/addons/KBE/face.py index 11ba33fa2..5d601e45b 100644 --- a/src/addons/KBE/face.py +++ b/src/addons/KBE/face.py @@ -1,22 +1,11 @@ -from OCC.BRep import BRep_Tool_Surface +from OCC.BRep import BRep_Tool_Surface, BRep_Tool from OCC.BRepIntCurveSurface import BRepIntCurveSurface_Inter -from OCC.BRepTools import BRepTools from OCC.BRepTopAdaptor import BRepTopAdaptor_FClass2d from OCC.Geom import Geom_Curve from OCC.GeomAPI import GeomAPI_ProjectPointOnSurf from OCC.GeomLib import GeomLib_IsPlanarSurface from OCC.TopAbs import TopAbs_IN from OCC.TopExp import TopExp - -__author__ = 'localadmin' -#=============================================================================== -# Surface.local_properties -# curvature, tangency etc. -#=============================================================================== -from OCC.KBE.base import Display, KbeObject, GlobalProperties -from OCC.KBE.edge import Edge -from OCC.Utils.Construct import * -from OCC.BRep import BRep_Tool from OCC.TopoDS import * from OCC.GeomLProp import GeomLProp_SLProps from OCC.BRepCheck import BRepCheck_Face @@ -26,8 +15,12 @@ from OCC.IntTools import IntTools_FaceFace from OCC.ShapeAnalysis import ShapeAnalysis_Surface from OCC.GeomProjLib import GeomProjLib -from OCC.Utils.Topology import Topo, WireExplorer +from OCC.Adaptor3d import Adaptor3d_IsoCurve +from OCC.KBE.base import Display, KbeObject, GlobalProperties +from OCC.KBE.edge import Edge +from OCC.Utils.Construct import * +from OCC.Utils.Topology import Topo, WireExplorer ''' @@ -44,7 +37,6 @@ ''' - class DiffGeomSurface(object): def __init__(self, instance): self.instance = instance @@ -170,11 +162,9 @@ def inflection_parameters(self): """ pass - #=============================================================================== # Surface.intersect #=============================================================================== - class IntersectSurface(object): def __init__(self, instance): self.instance = instance @@ -254,17 +244,11 @@ def u_continuity(self): def v_continuity (self): return self.adaptor.VContinuity() - # mehhh RuntimeError... - #def nb_u_knots = self.adaptor.NbUKnots - #def nb_v_knots = self.adaptor.NbVKnots - #def nb_u_poles = self.adaptor.NbUPoles - #def nb_v_poles = self.adaptor.NbVPoles - def domain(self): '''the u,v domain of the curve :return: UMin, UMax, VMin, VMax ''' - return BRepTools.UVBounds(self) + return BRepTools_UVBounds(self) def mid_point(self): """ @@ -342,7 +326,7 @@ def is_planar(self, tol=TOLERANCE): :return: bool, gp_Pln ''' aaa = GeomLib_IsPlanarSurface(self.surface_handle, tol) - return aaa.IsPlanar()# , aaa.Plan() + return aaa.IsPlanar() def is_trimmed(self): """ @@ -350,8 +334,6 @@ def is_trimmed(self): if this is not the case, the wire represents a contour that delimits the face [ think cookie cutter ] and implies that the surface is trimmed """ - #if not(BRep_Tool().NaturalRestriction(self)): - # return True _round = lambda x: round(x,3) a = map(_round, BRepTools_UVBounds(self)) b = map(_round, self.adaptor.Surface().Surface().GetObject().Bounds()) @@ -361,7 +343,6 @@ def is_trimmed(self): return False def is_overlapping(self, other): - import ipdb; ipdb.set_trace() overlap = IntTools_FaceFace() @@ -427,12 +408,6 @@ def project_vertex( self, pnt, tol=TOLERANCE): if isinstance(pnt, TopoDS_Vertex): pnt = BRep_Tool.Pnt(pnt) - #print "from OCC.ShapeAnalysis import ShapeAnalysis_Surface" -# from OCC.ShapeAnalysis import ShapeAnalysis_Surface -# -# ssa = ShapeAnalysis_Surface(self.surface_handle) -# ssa.NextValueOfUV() - proj = GeomAPI_ProjectPointOnSurf(pnt, self.surface_handle, tol) uv = proj.LowerDistanceParameters() proj_pnt = proj.NearestPoint() @@ -457,14 +432,6 @@ def project_edge(self, edg): return self.project_curve(self, self.adaptor) return self.project_curve(self, to_adaptor_3d(edg)) -# def iso_curve(self, u_or_v, param): -# """ -# :return: an iso curve at parameter `param` -# :param u_or_v: "u" or "v" -# :param param: the parameter where the iso curve lies -# """ -# pass - def iso_curve(self, u_or_v, param): """ get the iso curve from a u,v + parameter @@ -472,7 +439,6 @@ def iso_curve(self, u_or_v, param): :param param: :return: """ - from OCC.Adaptor3d import Adaptor3d_IsoCurve uv = 0 if u_or_v == 'u' else 1 # TODO: REFACTOR, part of the Face class now... iso = Adaptor3d_IsoCurve(self.adaptor_handle.GetHandle(), uv, param) @@ -488,10 +454,6 @@ def __str__(self): return self.__repr__() if __name__ == "__main__": - from OCC.BRepPrimAPI import BRepPrimAPI_MakeSphere sph = BRepPrimAPI_MakeSphere(1,1).Face() fc = Face(sph) - - - diff --git a/src/addons/KBE/plane.py b/src/addons/KBE/plane.py index b317c46ef..bb3dddec0 100644 --- a/src/addons/KBE/plane.py +++ b/src/addons/KBE/plane.py @@ -2,10 +2,6 @@ from OCC.GeomAPI import GeomAPI_IntCS, GeomAPI_IntSS from OCC.gp import gp_Pln -IntAna_Quadric # gp_* / gp_* intersect -IntAna_QuadQuadGeo -Extrema_ExtPElC - class Plane(object): # HalfSpace def __init__(self, pln): @@ -35,8 +31,3 @@ def project_curve(): def project_surface(): pass - - - - - diff --git a/src/addons/KBE/scratchpad.py b/src/addons/KBE/scratchpad.py index 41ab1baa8..8b1378917 100644 --- a/src/addons/KBE/scratchpad.py +++ b/src/addons/KBE/scratchpad.py @@ -1,5 +1 @@ -__author__ = 'jdf' -Curve - - \ No newline at end of file diff --git a/src/addons/KBE/shell.py b/src/addons/KBE/shell.py index 909e0dad9..5cc6c1456 100644 --- a/src/addons/KBE/shell.py +++ b/src/addons/KBE/shell.py @@ -1,11 +1,9 @@ -from .base import KbeObject, GlobalProperties -from .face import Face -from .wire import Wire - from OCC.TopoDS import TopoDS_Shell - from OCC.Utils.Topology import Topo +from base import KbeObject, GlobalProperties +from face import Face +from wire import Wire class DressUp(object): def __init__(self, instance): @@ -36,7 +34,6 @@ def chamfer_edge_distance_distance(self, edge, distance_this_face, distance_othe ''' pass - class Shell(KbeObject, TopoDS_Shell): _n = 0 def __init__(self, shell): @@ -73,4 +70,3 @@ def Wires(self): def Edges(self): return Topo(self, True).edges() - diff --git a/src/addons/KBE/solid.py b/src/addons/KBE/solid.py index 2440920d1..7f7dbc005 100644 --- a/src/addons/KBE/solid.py +++ b/src/addons/KBE/solid.py @@ -1,7 +1,8 @@ from OCC.TopoDS import TopoDS_Solid +from OCC.Utils.Topology import Topo + from base import GlobalProperties, KbeObject from shell import Shell -from OCC.Utils.Topology import Topo class Solid(KbeObject, TopoDS_Solid): @@ -13,17 +14,9 @@ def __init__(self, solid): self.GlobalProperties = GlobalProperties(self) self.DressUp = DressUp(self) - -# def parameter_to_coordinate(self, coord): -# ''' -# returns the index of the face closest to the world coordinate `coord` -# ''' -# raise NotImplementedError - #=============================================================================== # Solid.boolean #=============================================================================== - def add(self, other_solid): '''adds another_solid to self ''' @@ -51,4 +44,3 @@ def tesselation(self, angle): '''descriptor of the parameter controlling the precision of the tesselation ''' raise NotImplementedError - diff --git a/src/addons/KBE/types_lut.py b/src/addons/KBE/types_lut.py index 7d9547dcb..c23e83a8b 100644 --- a/src/addons/KBE/types_lut.py +++ b/src/addons/KBE/types_lut.py @@ -32,56 +32,6 @@ def __call__(self, shape): def __getitem__(self, item): return self(item) -#class ClassifyTopology(object): -# ''' -# returns what type `topoType` is -# -# const -# -# @param topoType: -# -# fundamental types to inherit from: -# TopoDS_Shape -# Adaptor3d_Curve -# Adaptor2d_Curve2d -# #gce_root -# -# ''' -# def __init__(self): -# ''' -# constructs a lookup of all (reasonbly) possible geometric OCC types -# ''' -# self.topoTypes = [TopoDS_Vertex,] -# -# self.adaptorTypes =[] -# self.gpTypes = [] -# -# self.topo_lookup = TopologyTypeLookup() -# self.adaptor_lookup = AdaptorTypeLookup() -# self.gp_lookup = GpTypeLookup() -# -# from OCC import TopoDS, gp, Adaptor2d, Adaptor3d -# -# def __getitem__(self, other): -# for i in _possible: -# if isinstance(topoType, i): -# return i -# -# def is_adaptor_curve_type(self, other): -# issubclass(other.__class__, Adaptor2d_Curve2d) or isinstance(other.__class__, Adaptor3d_Curve) -# -# def is_adaptor_surface_type(self, other): -# issubclass(other.__class__, Adaptor3d_Surface) -# -# def is_adaptor_type(self, other): -# return True if self.is_adaptor_curve_type(other) or self.is_adaptor_surface_type(other) else False -# -# def is_topods_type(self, other): -# issubclass(other.__class__, TopoDS_Shape) -# -# def is_gp_type(self, other): -# return True if other.__class__.__name__.split('_')[0] == 'gp' or 'jajaja' else False - class EnumLookup(object): """ perform bi-directional lookup of Enums'... @@ -215,4 +165,3 @@ def shape_is_cylinder(face): return False else: return True - diff --git a/src/addons/KBE/vertex.py b/src/addons/KBE/vertex.py index 48fb797ad..7a8e308f0 100644 --- a/src/addons/KBE/vertex.py +++ b/src/addons/KBE/vertex.py @@ -1,18 +1,13 @@ -#from OCC.Utils.Construct import make_vertex from OCC.BRepPrimAPI import * - from OCC.Utils.Construct import make_vertex - from OCC.Utils.Common import TOLERANCE, vertex2pnt from OCC.gp import gp_Pnt, gp_Trsf from OCC.TopoDS import TopoDS_Vertex -from base import KbeObject from OCC.BRepTools import BRepTools_TrsfModification +from OCC.ShapeBuild import ShapeBuild_ReShape - -def make_vertex(*args): - return BRepBuilderAPI_MakeVertex(*args) +from base import KbeObject class Vertex(KbeObject, TopoDS_Vertex): """ @@ -34,10 +29,8 @@ def _update(self): """ # TODO: perhaps should take an argument until which topological level # topological entities bound to the vertex should be updated too... - from OCC.ShapeBuild import ShapeBuild_ReShape reshape = ShapeBuild_ReShape() reshape.Replace(self._vertex, make_vertex(self._pnt)) - #self = Vertex(*self._pnt.Coord()) @staticmethod def from_vertex(cls, pnt): @@ -60,7 +53,6 @@ def x(self): def x(self, val): self._pnt.SetX(val) self._update() - #self.is_dirty = 1 @property def y(self): @@ -70,7 +62,6 @@ def y(self): def y(self, val): self._pnt.SetY(val) self._update() - #self.is_dirty = 1 @property def z(self): @@ -80,7 +71,6 @@ def z(self): def z(self, val): self._pnt.SetZ(val) self._update() - #self.is_dirty = 1 @property def xyz(self): @@ -90,8 +80,6 @@ def xyz(self): def xyz(self, *val): self._pnt.SetXYZ(*val) self._update() - #self.is_dirty = 1 - def __repr__(self): return self.name @@ -103,7 +91,7 @@ def as_vec(self): @property def as_dir(self): - '''returns a gp_Vec version of self''' + '''returns a gp_Dir version of self''' return gp_Dir(*self._pnt.Coord()) @property @@ -119,7 +107,3 @@ def as_pnt(self): def as_2d(self): '''returns a gp_Pnt2d version of self''' return gp_Pnt2d(*self._pnt.Coord()[:2]) - - - - diff --git a/src/addons/KBE/wire.py b/src/addons/KBE/wire.py index 3f2a65fdb..991592ab6 100644 --- a/src/addons/KBE/wire.py +++ b/src/addons/KBE/wire.py @@ -12,5 +12,3 @@ def __init__(self, wire): assert isinstance(wire, TopoDS_wire), 'need a TopoDS_Wire, got a %s'% wire.__class__ KbeObject.__init__(self, 'wire') TopoDS_Wire.__init__(self, wire) - - # BRepAdaptor_CompCurve \ No newline at end of file diff --git a/src/addons/Utils/Common.py b/src/addons/Utils/Common.py index 712bcbd33..d3bd0a1c8 100644 --- a/src/addons/Utils/Common.py +++ b/src/addons/Utils/Common.py @@ -629,4 +629,3 @@ def adapt_edge_to_hcurve(edg): c = BRepAdaptor_HCurve() c.ChangeCurve().Initialize(edg) return c - diff --git a/src/addons/Utils/Construct.py b/src/addons/Utils/Construct.py index 5a725e449..7e64beed3 100644 --- a/src/addons/Utils/Construct.py +++ b/src/addons/Utils/Construct.py @@ -46,7 +46,6 @@ from functools import wraps import warnings, operator, math - EPSILON = TOLERANCE = 1e-6 ST = ShapeToTopology() diff --git a/src/addons/Utils/Iteration.py b/src/addons/Utils/Iteration.py index bbd5ca510..5f9c8c02e 100644 --- a/src/addons/Utils/Iteration.py +++ b/src/addons/Utils/Iteration.py @@ -5,8 +5,6 @@ from OCC.Utils.Topology import WireExplorer, Topo from OCC.KBE.edge import Edge -# TODO: needs unit testing - class EdgePairsFromWire(object): ''' helper class to loop through a wire and return ordered pairs of edges diff --git a/src/addons/Utils/Topology.py b/src/addons/Utils/Topology.py index 8c7dba232..f7cb599e7 100644 --- a/src/addons/Utils/Topology.py +++ b/src/addons/Utils/Topology.py @@ -1 +1 @@ -# -*- coding: iso-8859-1 -*- #!/usr/bin/env python ##Copyright 2008-2011 Jelle Feringa (jelleferinga@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC 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 3 of the License, or ##(at your option) any later version. ## ##pythonOCC 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 pythonOCC. If not, see . ''' TODO: Hide WireExplorer... BRepTools.Map3DEdges() History: 20-01-2009: initial version 23-03-2009: completed and updated for modular pythonOCC build 23-04-2009: fixed a reference issue ( fixed using ReInit ) ''' from OCC.TopAbs import * from OCC.TopExp import * from OCC.TopoDS import * from OCC.TopTools import * from OCC.BRepTools import * from OCC.BRep import * from OCC.KBE.types_lut import topo_lut, shape_lut from OCC.KBE.edge import Edge from OCC.Utils.Construct import vertex2pnt import sys, itertools __all__ = ['Topo', 'WireExplorer'] class WireExplorer(object): ''' ''' def __init__(self, wire, kbe_types=False): assert isinstance(wire, TopoDS_Wire), 'not a TopoDS_Wire' self.kbe_types = kbe_types self.wire = wire self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _reinitialize(self): self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _loop_topo(self, edges=True): if self.done: self._reinitialize() topologyType = TopoDS_edge if edges else TopoDS_vertex seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.wire_explorer.More(): # loop edges if edges: current_item = self.wire_explorer.Current() # loop vertices else: current_item = self.wire_explorer.CurrentVertex() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.wire_explorer.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = topologyType(occ_iterator.Value()) if self.kbe_types and edges: edge = Edge(topo_to_add) seq.append(edge) else: seq.append(topo_to_add) occ_iterator.Next() self.done = True return iter(seq) def ordered_edges(self): return self._loop_topo(edges=True) def ordered_vertices(self): return self._loop_topo(edges=False) class Topo(object): ''' Topology traversal ''' def __init__(self, myShape, kbe_types=False, ignore_orientation=False): """ implements topology traversal from any TopoDS_Shape this class lets you find how various topological entities are connected from one to another find the faces connected to an edge, find the vertices this edge is made from, get all faces connected to a vertex, and find out how many topological elements are connected from a source *note* when traversing TopoDS_Wire entities, its advised to use the specialized ``WireExplorer`` class, which will return the vertices / edges in the expected order :param myShape: the shape which topology will be traversed :param kbe_types: whether to return OCC.KBE topology types KBE types offers a more consistent and pythonic API, since many useful methods are bound to these objects :param ignore_orientation: filter out TopoDS_* entities of similar TShape but different Orientation for instance, a cube has 24 edges, 4 edges for each of 6 faces that results in 48 vertices, while there are only 8 vertices that have a unique geometric coordinate in certain cases ( computing a graph from the topology ) its preferable to return topological entities that share similar geometry, though differ in orientation by setting the ``ignore_orientation`` variable to True, in case of a cube, just 12 edges and only 8 vertices will be returned for further reference see TopoDS_Shape IsEqual / IsSame methods """ self.myShape = myShape self.kbe_types = kbe_types self.ignore_orientation = ignore_orientation self.topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid } if self.kbe_types: from OCC.KBE.vertex import Vertex from OCC.KBE.edge import Edge from OCC.KBE.face import Face from OCC.KBE.solid import Shell, Solid self.kbeTypes = { TopAbs_VERTEX: Vertex, TopAbs_EDGE: Edge, TopAbs_FACE: Face, TopAbs_SHELL: Shell, TopAbs_SOLID: Solid, } def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=None): ''' this could be a faces generator for a python TopoShape class that way you can just do: for face in srf.faces(): processFace(face) ''' topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid} assert topologyType in self.topoTypes.keys(), '%s not one of %s' %( topologyType, self.topoTypes.keys() ) self.topExp = TopExp_Explorer() # use self.myShape if nothing is specified if topologicalEntity is None and topologyTypeToAvoid is None: self.topExp.Init(self.myShape, topologyType) elif topologicalEntity is None and topologyTypeToAvoid is not None: self.topExp.Init(self.myShape, topologyType, topologyTypeToAvoid) elif topologyTypeToAvoid is None: self.topExp.Init(topologicalEntity, topologyType ) elif topologyTypeToAvoid: self.topExp.Init(topologicalEntity, topologyType, topologyTypeToAvoid) topo_set = set() seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.topExp.More(): current_item = self.topExp.Current() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.topExp.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = self.topoTypes[topologyType](occ_iterator.Value()) # return a KBE type if self.kbe_types: if topologyType in self.kbeTypes: seq.append(self.kbeTypes[topologyType](topo_to_add)) # otherwise a plain TopoDS_Shape subclass else: seq.append(topo_to_add) occ_iterator.Next() if self.ignore_orientation: # filter out those entities that share the same TShape # but do *not* share the same orientation filter_orientation_seq = [] for i in seq: _present = False for j in filter_orientation_seq: if i.IsSame(j): _present = True break if _present is False: filter_orientation_seq.append(i) return filter_orientation_seq else: return iter(seq) def faces(self): ''' loops over all faces ''' return self._loop_topo(TopAbs_FACE) def _number_of_topo(self, iterable): n = 0 for i in iterable: n+=1 return n def number_of_faces(self): return self._number_of_topo(self.faces()) def vertices(self): ''' loops over all vertices ''' return self._loop_topo(TopAbs_VERTEX) def number_of_vertices(self): return self._number_of_topo(self.vertices()) def edges(self): ''' loops over all edges ''' return self._loop_topo(TopAbs_EDGE) def number_of_edges(self): return self._number_of_topo(self.edges()) def wires(self): ''' loops over all wires ''' return self._loop_topo(TopAbs_WIRE) def number_of_wires(self): return self._number_of_topo(self.wires()) def shells(self): ''' loops over all shells ''' return self._loop_topo(TopAbs_SHELL, None) def number_of_shells(self): return self._number_of_topo(self.shells()) def solids(self): ''' loops over all solids ''' return self._loop_topo(TopAbs_SOLID, None) def number_of_solids(self): return self._number_of_topo(self.solids()) def comp_solids(self): ''' loops over all compound solids ''' return self._loop_topo(TopAbs_COMPSOLID) def number_of_comp_solids(self): return self._number_of_topo(self.comp_solids()) def compounds(self): ''' loops over all compounds ''' return self._loop_topo(TopAbs_COMPOUND) def number_of_compounds(self): return self._number_of_topo(self.compounds()) def ordered_vertices_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_vertices() def number_of_ordered_vertices_from_wire(self, wire): return self._number_of_topo(self.ordered_vertices_from_wire(wire)) def ordered_edges_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_edges() def number_of_ordered_edges_from_wire(self, wire): return self._number_of_topo(self.ordered_edges_from_wire(wire)) def _map_shapes_and_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): ''' using the same method @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): yield None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_entity = self.topoTypes[topoTypeB](topology_iterator.Value()) if self.kbe_types: if topoTypeB in self.kbeTypes: topo_entity = self.kbeTypes[topoTypeB](topo_entity) else: raise ValueError('none KBE types called') # return the entity if not in set # to assure we're not returning entities several times if not topo_entity in topo_set: if self.ignore_orientation: unique=True for i in topo_set: if i.IsSame(topo_entity): unique=False break if unique: yield topo_entity else: yield topo_entity topo_set.add(topo_entity) topology_iterator.Next() def _number_shapes_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): '''returns the number of shape ancestors If you want to know how many edges a faces has: _number_shapes_ancestors(self, TopAbs_EDGE, TopAbs_FACE, edg) will return the number of edges a faces has @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): return None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_set.add(topology_iterator.Value()) topology_iterator.Next() return len(topo_set) #=============================================================================== # EDGE <-> FACE #=============================================================================== def faces_from_edge(self, edge): """ :param edge: :return: """ return self._map_shapes_and_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def number_of_faces_from_edge(self, edge): """ :param edge: :return: """ return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def edges_from_face(self, face): """ :param face: :return: """ return self._loop_topo(TopAbs_EDGE, face) def number_of_edges_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, face): cnt += 1 return cnt #=============================================================================== # VERTEX <-> EDGE #=============================================================================== def vertices_from_edge(self, edg): return self._loop_topo(TopAbs_VERTEX, edg) def number_of_vertices_from_edge(self, edg): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, edg): cnt += 1 return cnt def edges_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_EDGE,vertex) def number_of_edges_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_EDGE,vertex) #=============================================================================== # WIRE <-> EDGE #=============================================================================== def edges_from_wire(self, wire): return self._loop_topo(TopAbs_EDGE, wire) def number_of_edges_from_wire(self, wire): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, wire): cnt += 1 return cnt def wires_from_edge(self, edg): return self._map_shapes_and_ancestors(TopAbs_EDGE, TopAbs_WIRE, edg) def wires_from_vertex(self, edg): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_WIRE, edg) def number_of_wires_from_edge(self, edg): return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_WIRE, edg) #=============================================================================== # WIRE <-> FACE #=============================================================================== def wires_from_face(self, face): return self._loop_topo(TopAbs_WIRE, face) def number_of_wires_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_WIRE, face): cnt += 1 return cnt def faces_from_wire(self, wire): return self._map_shapes_and_ancestors(TopAbs_WIRE, TopAbs_FACE, wire) def number_of_faces_from_wires(self, wire): return self._number_shapes_ancestors(TopAbs_WIRE,TopAbs_FACE, wire) #=============================================================================== # VERTEX <-> FACE #=============================================================================== def faces_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def number_of_faces_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def vertices_from_face(self, face): return self._loop_topo(TopAbs_VERTEX, face) def number_of_vertices_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, face): cnt += 1 return cnt #=============================================================================== # FACE <-> SOLID #=============================================================================== def solids_from_face(self, face): return self._map_shapes_and_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def number_of_solids_from_face(self, face): return self._number_shapes_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def faces_from_solids(self, solid): return self._loop_topo(TopAbs_FACE, solid) def number_of_faces_from_solids(self, solid): cnt = 0 for i in self._loop_topo(TopAbs_FACE, solid): cnt += 1 return cnt def dump_topology(shape,level=0): """ Print the details of an object from the top down """ brt = BRep_Tool() s = shape.ShapeType() ts = TopoDS.TopoDS() print print "." * level,topo_lut[shape.ShapeType()], if s == TopAbs_VERTEX: pnt = vertex2pnt(shape_lut[shape]) print "" % (pnt.X(), pnt.Y(), pnt.Z()) it = TopoDS.TopoDS_Iterator(shape) while it.More(): shp = it.Value() it.Next() dump_topology(shp,level + 1 ) def shapeTypeString(shape): st = shape.ShapeType() s = "?" if st == TopAbs_VERTEX: s = "Vertex" if st == TopAbs_SOLID: s = "Solid" if st == TopAbs_EDGE: s = "Edge" if st == TopAbs_FACE: s = "Face" if st == TopAbs_SHELL: s = "Shell" if st == TopAbs_WIRE: s = "Wire" if st == TopAbs_COMPOUND: s = "Compound." if st == TopAbs_COMPSOLID: s = "Compsolid." return s + ":" + str(shape.HashCode(23232232)) \ No newline at end of file +# -*- coding: iso-8859-1 -*- #!/usr/bin/env python ##Copyright 2008-2011 Jelle Feringa (jelleferinga@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC 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 3 of the License, or ##(at your option) any later version. ## ##pythonOCC 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 pythonOCC. If not, see . ''' TODO: Hide WireExplorer... BRepTools.Map3DEdges() History: 20-01-2009: initial version 23-03-2009: completed and updated for modular pythonOCC build 23-04-2009: fixed a reference issue ( fixed using ReInit ) ''' from OCC.TopAbs import * from OCC.TopExp import * from OCC.TopoDS import * from OCC.TopTools import * from OCC.BRepTools import * from OCC.BRep import * from OCC.KBE.types_lut import topo_lut, shape_lut from OCC.KBE.edge import Edge from OCC.Utils.Construct import vertex2pnt import sys, itertools __all__ = ['Topo', 'WireExplorer'] class WireExplorer(object): ''' ''' def __init__(self, wire, kbe_types=False): assert isinstance(wire, TopoDS_Wire), 'not a TopoDS_Wire' self.kbe_types = kbe_types self.wire = wire self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _reinitialize(self): self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _loop_topo(self, edges=True): if self.done: self._reinitialize() topologyType = TopoDS_edge if edges else TopoDS_vertex seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.wire_explorer.More(): # loop edges if edges: current_item = self.wire_explorer.Current() # loop vertices else: current_item = self.wire_explorer.CurrentVertex() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.wire_explorer.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = topologyType(occ_iterator.Value()) if self.kbe_types and edges: edge = Edge(topo_to_add) seq.append(edge) else: seq.append(topo_to_add) occ_iterator.Next() self.done = True return iter(seq) def ordered_edges(self): return self._loop_topo(edges=True) def ordered_vertices(self): return self._loop_topo(edges=False) class Topo(object): ''' Topology traversal ''' def __init__(self, myShape, kbe_types=False, ignore_orientation=False): """ implements topology traversal from any TopoDS_Shape this class lets you find how various topological entities are connected from one to another find the faces connected to an edge, find the vertices this edge is made from, get all faces connected to a vertex, and find out how many topological elements are connected from a source *note* when traversing TopoDS_Wire entities, its advised to use the specialized ``WireExplorer`` class, which will return the vertices / edges in the expected order :param myShape: the shape which topology will be traversed :param kbe_types: whether to return OCC.KBE topology types KBE types offers a more consistent and pythonic API, since many useful methods are bound to these objects :param ignore_orientation: filter out TopoDS_* entities of similar TShape but different Orientation for instance, a cube has 24 edges, 4 edges for each of 6 faces that results in 48 vertices, while there are only 8 vertices that have a unique geometric coordinate in certain cases ( computing a graph from the topology ) its preferable to return topological entities that share similar geometry, though differ in orientation by setting the ``ignore_orientation`` variable to True, in case of a cube, just 12 edges and only 8 vertices will be returned for further reference see TopoDS_Shape IsEqual / IsSame methods """ self.myShape = myShape self.kbe_types = kbe_types self.ignore_orientation = ignore_orientation self.topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid } if self.kbe_types: from OCC.KBE.vertex import Vertex from OCC.KBE.edge import Edge from OCC.KBE.face import Face from OCC.KBE.solid import Shell, Solid self.kbeTypes = { TopAbs_VERTEX: Vertex, TopAbs_EDGE: Edge, TopAbs_FACE: Face, TopAbs_SHELL: Shell, TopAbs_SOLID: Solid, } def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=None): ''' this could be a faces generator for a python TopoShape class that way you can just do: for face in srf.faces: processFace(face) ''' topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid} assert topologyType in topoTypes.keys(), '%s not one of %s' %( topologyType, topoTypes.keys() ) self.topExp = TopExp_Explorer() # use self.myShape if nothing is specified if topologicalEntity is None and topologyTypeToAvoid is None: self.topExp.Init(self.myShape, topologyType) elif topologicalEntity is None and topologyTypeToAvoid is not None: self.topExp.Init(self.myShape, topologyType, topologyTypeToAvoid) elif topologyTypeToAvoid is None: self.topExp.Init(topologicalEntity, topologyType ) elif topologyTypeToAvoid: self.topExp.Init(topologicalEntity, topologyType, topologyTypeToAvoid) topo_set = set() seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.topExp.More(): current_item = self.topExp.Current() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.topExp.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = self.topoTypes[topologyType](occ_iterator.Value()) # return a KBE type if self.kbe_types: if topologyType in self.kbeTypes: seq.append(self.kbeTypes[topologyType](topo_to_add)) # otherwise a plain TopoDS_Shape subclass else: seq.append(topo_to_add) occ_iterator.Next() if self.ignore_orientation: # filter out those entities that share the same TShape # but do *not* share the same orientation filter_orientation_seq = [] for i in seq: _present = False for j in filter_orientation_seq: if i.IsSame(j): _present = True break if _present is False: filter_orientation_seq.append(i) return filter_orientation_seq else: return iter(seq) def faces(self): ''' loops over all faces ''' return self._loop_topo(TopAbs_FACE) def _number_of_topo(self, iterable): n = 0 for i in iterable: n+=1 return n def number_of_faces(self): return self._number_of_topo(self.faces()) def vertices(self): ''' loops over all vertices ''' return self._loop_topo(TopAbs_VERTEX) def number_of_vertices(self): return self._number_of_topo(self.vertices()) def edges(self): ''' loops over all edges ''' return self._loop_topo(TopAbs_EDGE) def number_of_edges(self): return self._number_of_topo(self.edges()) def wires(self): ''' loops over all wires ''' return self._loop_topo(TopAbs_WIRE) def number_of_wires(self): return self._number_of_topo(self.wires()) def shells(self): ''' loops over all shells ''' return self._loop_topo(TopAbs_SHELL, None) def number_of_shells(self): return self._number_of_topo(self.shells()) def solids(self): ''' loops over all solids ''' return self._loop_topo(TopAbs_SOLID, None) def number_of_solids(self): return self._number_of_topo(self.solids()) def comp_solids(self): ''' loops over all compound solids ''' return self._loop_topo(TopAbs_COMPSOLID) def number_of_comp_solids(self): return self._number_of_topo(self.comp_solids()) def compounds(self): ''' loops over all compounds ''' return self._loop_topo(TopAbs_COMPOUND) def number_of_compounds(self): return self._number_of_topo(self.compounds()) def ordered_vertices_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_vertices() def number_of_ordered_vertices_from_wire(self, wire): return self._number_of_topo(self.ordered_vertices_from_wire(wire)) def ordered_edges_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_edges() def number_of_ordered_edges_from_wire(self, wire): return self._number_of_topo(self.ordered_edges_from_wire(wire)) def _map_shapes_and_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): ''' using the same method @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): yield None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_entity = self.topoTypes[topoTypeB](topology_iterator.Value()) if self.kbe_types: if topoTypeB in self.kbeTypes: topo_entity = self.kbeTypes[topoTypeB](topo_entity) else: raise ValueError('none KBE types called') # return the entity if not in set # to assure we're not returning entities several times if not topo_entity in topo_set: if self.ignore_orientation: unique=True for i in topo_set: if i.IsSame(topo_entity): unique=False break if unique: yield topo_entity else: yield topo_entity topo_set.add(topo_entity) topology_iterator.Next() def _number_shapes_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): '''returns the number of shape ancestors If you want to know how many edges a faces has: _number_shapes_ancestors(self, TopAbs_EDGE, TopAbs_FACE, edg) will return the number of edges a faces has @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): return None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_set.add(topology_iterator.Value()) topology_iterator.Next() return len(topo_set) #=============================================================================== # EDGE <-> FACE #=============================================================================== def faces_from_edge(self, edge): """ :param edge: :return: """ return self._map_shapes_and_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def number_of_faces_from_edge(self, edge): """ :param edge: :return: """ return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def edges_from_face(self, face): """ :param face: :return: """ return self._loop_topo(TopAbs_EDGE, face) def number_of_edges_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, face): cnt += 1 return cnt #=============================================================================== # VERTEX <-> EDGE #=============================================================================== def vertices_from_edge(self, edg): return self._loop_topo(TopAbs_VERTEX, edg) def number_of_vertices_from_edge(self, edg): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, edg): cnt += 1 return cnt def edges_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_EDGE,vertex) def number_of_edges_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_EDGE,vertex) #=============================================================================== # WIRE <-> EDGE #=============================================================================== def edges_from_wire(self, wire): return self._loop_topo(TopAbs_EDGE, wire) def number_of_edges_from_wire(self, wire): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, wire): cnt += 1 return cnt def wires_from_edge(self, edg): return self._map_shapes_and_ancestors(TopAbs_EDGE, TopAbs_WIRE, edg) def wires_from_vertex(self, edg): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_WIRE, edg) def number_of_wires_from_edge(self, edg): return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_WIRE, edg) #=============================================================================== # WIRE <-> FACE #=============================================================================== def wires_from_face(self, face): return self._loop_topo(TopAbs_WIRE, face) def number_of_wires_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_WIRE, face): cnt += 1 return cnt def faces_from_wire(self, wire): return self._map_shapes_and_ancestors(TopAbs_WIRE, TopAbs_FACE, wire) def number_of_faces_from_wires(self, wire): return self._number_shapes_ancestors(TopAbs_WIRE,TopAbs_FACE, wire) #=============================================================================== # VERTEX <-> FACE #=============================================================================== def faces_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def number_of_faces_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def vertices_from_face(self, face): return self._loop_topo(TopAbs_VERTEX, face) def number_of_vertices_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, face): cnt += 1 return cnt #=============================================================================== # FACE <-> SOLID #=============================================================================== def solids_from_face(self, face): return self._map_shapes_and_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def number_of_solids_from_face(self, face): return self._number_shapes_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def faces_from_solids(self, solid): return self._loop_topo(TopAbs_FACE, solid) def number_of_faces_from_solids(self, solid): cnt = 0 for i in self._loop_topo(TopAbs_FACE, solid): cnt += 1 return cnt def dump_topology(shape,level=0): """ Print the details of an object from the top down """ brt = BRep_Tool() s = shape.ShapeType() ts = TopoDS.TopoDS() print print "." * level,topo_lut[shape.ShapeType()], if s == TopAbs_VERTEX: pnt = vertex2pnt(shape_lut[shape]) print "" % (pnt.X(), pnt.Y(), pnt.Z()) it = TopoDS.TopoDS_Iterator(shape) while it.More(): shp = it.Value() it.Next() dump_topology(shp,level + 1 ) def shapeTypeString(shape): st = shape.ShapeType() s = "?" if st == TopAbs_VERTEX: s = "Vertex" if st == TopAbs_SOLID: s = "Solid" if st == TopAbs_EDGE: s = "Edge" if st == TopAbs_FACE: s = "Face" if st == TopAbs_SHELL: s = "Shell" if st == TopAbs_WIRE: s = "Wire" if st == TopAbs_COMPOUND: s = "Compound." if st == TopAbs_COMPSOLID: s = "Compsolid." return s + ":" + str(shape.HashCode(23232232)) \ No newline at end of file From bf6d58a6fb430c151614c5c7a4552de3a05b9593 Mon Sep 17 00:00:00 2001 From: jf--- Date: Fri, 1 Nov 2013 13:53:35 +0100 Subject: [PATCH 20/29] WIP commit --- src/addons/DataExchange/utils.py | 2 +- src/addons/Display/OCCViewer.py | 9 +- src/addons/Display/qtDisplay.py | 13 +- src/addons/Display/wxDisplay.py | 6 +- src/addons/KBE/edge.py | 4 +- src/addons/KBE/face.py | 3 +- src/addons/KBE/vertex.py | 2 +- src/addons/Utils/Common.py | 32 ++ src/addons/Utils/Construct.py | 2 +- src/addons/Utils/Topology.py | 2 +- .../smesh-5.1.2.2/inc/SMESH_MeshVSLink.hxx | 51 +- .../src/SMESH/SMESH_MeshVSLink.cpp | 505 +++++++++--------- src/examples/DYN/dyn_demo.py | 8 +- src/examples/GEOM/partition.py | 14 +- 14 files changed, 365 insertions(+), 288 deletions(-) diff --git a/src/addons/DataExchange/utils.py b/src/addons/DataExchange/utils.py index b5e4e7551..0a76c44ee 100644 --- a/src/addons/DataExchange/utils.py +++ b/src/addons/DataExchange/utils.py @@ -71,7 +71,7 @@ def file_to_shape(pth): stl_reader = StlAPI.StlAPI_Reader() stl_reader.Read(shape,pth) return shape - + reader.ReadFile(pth) n_translated = reader.TransferRoots() shape = reader.OneShape() diff --git a/src/addons/Display/OCCViewer.py b/src/addons/Display/OCCViewer.py index 3f793b05b..47d846844 100644 --- a/src/addons/Display/OCCViewer.py +++ b/src/addons/Display/OCCViewer.py @@ -77,7 +77,8 @@ def SetWindow(self,window_handle): self._window_handle = window_handle def Create(self, create_default_lights = True): - if sys.platform!='win32': + # applies merely for X11 + if sys.platform!='win32' and sys.platform != "darwin": try: os.environ['DISPLAY'] except KeyError: @@ -308,13 +309,15 @@ def DisplayColoredShape(self, shapes, color='YELLOW', update=False, ): 'WHITE':OCC.Quantity.Quantity_NOC_WHITE, 'BLACK':OCC.Quantity.Quantity_NOC_BLACK, 'ORANGE':OCC.Quantity.Quantity_NOC_ORANGE, } + clr = Quantity_Color( dict_color[color] ) elif isinstance(color, Quantity_Color): clr = color else: - raise ValueError('color should either be a string ( "BLUE" ) or a Quantity_Color(0.1, 0.8, 0.1) got %s' % color) + msg = 'color should either be a string ( "BLUE" ) or a Quantity_Color(0.1, 0.8, 0.1) got %s' % color + raise ValueError(msg) - return self.DisplayShape(shapes, color=clr, update=update) + return self.DisplayShape(shapes, color=clr, update=update) def DisplayTriedron(self): diff --git a/src/addons/Display/qtDisplay.py b/src/addons/Display/qtDisplay.py index dbff052a5..777ea8d0a 100644 --- a/src/addons/Display/qtDisplay.py +++ b/src/addons/Display/qtDisplay.py @@ -17,9 +17,7 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -import os - -import sys +import os,sys from PyQt4 import QtCore, QtGui, QtOpenGL import OCCViewer @@ -39,6 +37,8 @@ class qtBaseViewer(QtOpenGL.QGLWidget): ''' def __init__(self, parent = None): QtOpenGL.QGLWidget.__init__(self,parent) + # self.initializeGL() + # self.initializeOverlayGL() self._display = None self._inited = False self.setMouseTracking(True) #enable Mouse Tracking @@ -157,7 +157,12 @@ def mouseReleaseEvent(self, event): selected_shapes = self._display.SelectArea(Xmin,Ymin,Xmin+dx,Ymin+dy) self._select_area = False else: - self._display.Select(pt.x,pt.y) + # multiple select if shift is pressed + if QtCore.Qt.ShiftModifier: + self._display.ShiftSelect(pt.x,pt.y) + else: + # single select otherwise + self._display.Select(pt.x, pt.y) elif event.button() == QtCore.Qt.RightButton: if self._zoom_area: [Xmin, Ymin, dx, dy] = self._drawbox diff --git a/src/addons/Display/wxDisplay.py b/src/addons/Display/wxDisplay.py index 1e9ece6a1..9314d9fef 100644 --- a/src/addons/Display/wxDisplay.py +++ b/src/addons/Display/wxDisplay.py @@ -213,7 +213,11 @@ def OnLeftUp(self,evt): selected_shapes = self._display.SelectArea(Xmin,Ymin,Xmin+dx,Ymin+dy) self._select_area = False else: - self._display.Select(pt.x,pt.y) + shift_down = wx.GetMouseState().ShiftDown() + if shift_down: + self._display.ShiftSelect(pt.x,pt.y) + else: + self._display.Select(pt.x,pt.y) def OnRightUp(self,evt): if self._zoom_area: diff --git a/src/addons/KBE/edge.py b/src/addons/KBE/edge.py index 9371994c2..4a0568830 100644 --- a/src/addons/KBE/edge.py +++ b/src/addons/KBE/edge.py @@ -16,7 +16,7 @@ from OCC.Utils.Common import vertex2pnt, minimum_distance from OCC.Utils.Construct import make_edge, fix_continuity from OCC.Utils.Context import assert_isdone -from OCC.KBE.vertex import Vertex +# from OCC.KBE.vertex import Vertex from OCC.KBE.types_lut import geom_lut from OCC.KBE.base import KbeObject @@ -253,7 +253,7 @@ def _local_properties(self): self._lprops_curve_tool = GeomLProp_CurveTool() self._local_properties_init = True - def domain(self): + def domain(self, trimmed_domain=False): '''returns the u,v domain of the curve''' return self.adaptor.FirstParameter(), self.adaptor.LastParameter() diff --git a/src/addons/KBE/face.py b/src/addons/KBE/face.py index 5d601e45b..697f59b42 100644 --- a/src/addons/KBE/face.py +++ b/src/addons/KBE/face.py @@ -255,8 +255,7 @@ def mid_point(self): :return: the parameter at the mid point of the face, and its corresponding gp_Pnt """ u_min, u_max, v_min, v_max = self.domain() - u_mid = (u_min + u_max) / 2. - v_mid = (v_min + v_max) / 2. + u_mid, v_mid = u_min + (u_max - u_min) / 2., v_min + (v_max - v_min) / 2. pnt = self.parameter_to_point(u_mid, v_mid) return ( (u_mid, v_mid), self.adaptor.Value(u_mid, v_mid) ) diff --git a/src/addons/KBE/vertex.py b/src/addons/KBE/vertex.py index 7a8e308f0..b46b47b1e 100644 --- a/src/addons/KBE/vertex.py +++ b/src/addons/KBE/vertex.py @@ -7,7 +7,7 @@ from OCC.BRepTools import BRepTools_TrsfModification from OCC.ShapeBuild import ShapeBuild_ReShape -from base import KbeObject +from OCC.KBE.base import KbeObject class Vertex(KbeObject, TopoDS_Vertex): """ diff --git a/src/addons/Utils/Common.py b/src/addons/Utils/Common.py index d3bd0a1c8..86008f6d7 100644 --- a/src/addons/Utils/Common.py +++ b/src/addons/Utils/Common.py @@ -402,6 +402,38 @@ def intersection_from_three_planes( planeA, planeB, planeC): pnt = intersection_planes.Value() return pnt +def intersect_plane_line(pln, li): + + """ + + :param pln: gp_Pln or Geom_Plane + :param li: gp_Lin + """ + + from OCC.Geom import Geom_Plane, Geom_Line + _li = Geom_Line(li) + + if isinstance(pln, gp_Pln): + _pln = Geom_Plane(pln) + elif isinstance(pln, Geom_Plane): + _pln = pln + else: + raise ValueError("the `pln` argument either is a gp_Pln or a Geom_Plane, but a {0}\ + argument was supplied".format(pln.__class__)) + + intersect_ = GeomAPI_IntCS() + intersect_.Perform(_li.GetHandle(), _pln.GetHandle()) + if intersect_.IsDone(): + if intersect_.NbPoints() == 0: + return None + elif intersect_.NbPoints() ==1: + return intersect_.Point(1) + else: + raise ValueError("found more than one intersection of a line and a plane...\ + expected just a single intersection") + else: + return None + def intersect_shape_by_line(topods_shape, line, low_parameter=0.0, hi_parameter=float("+inf")): """ finds the intersection of a shape and a line diff --git a/src/addons/Utils/Construct.py b/src/addons/Utils/Construct.py index 7e64beed3..dab099399 100644 --- a/src/addons/Utils/Construct.py +++ b/src/addons/Utils/Construct.py @@ -503,7 +503,7 @@ def make_n_sided(edges, points, continuity=GeomAbs_C0): :return: TopoDS_Face """ from OCC.BRepFill import BRepFill_Filling - n_sided = BRepFill_Filling(NbIter=6) + n_sided = BRepFill_Filling()#NbIter=6) #n_sided.SetApproxParam( 6, 40) #n_sided.SetResolParam( 3, 20, 20, False) for edg in edges: diff --git a/src/addons/Utils/Topology.py b/src/addons/Utils/Topology.py index f7cb599e7..3f8b814f1 100644 --- a/src/addons/Utils/Topology.py +++ b/src/addons/Utils/Topology.py @@ -1 +1 @@ -# -*- coding: iso-8859-1 -*- #!/usr/bin/env python ##Copyright 2008-2011 Jelle Feringa (jelleferinga@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC 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 3 of the License, or ##(at your option) any later version. ## ##pythonOCC 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 pythonOCC. If not, see . ''' TODO: Hide WireExplorer... BRepTools.Map3DEdges() History: 20-01-2009: initial version 23-03-2009: completed and updated for modular pythonOCC build 23-04-2009: fixed a reference issue ( fixed using ReInit ) ''' from OCC.TopAbs import * from OCC.TopExp import * from OCC.TopoDS import * from OCC.TopTools import * from OCC.BRepTools import * from OCC.BRep import * from OCC.KBE.types_lut import topo_lut, shape_lut from OCC.KBE.edge import Edge from OCC.Utils.Construct import vertex2pnt import sys, itertools __all__ = ['Topo', 'WireExplorer'] class WireExplorer(object): ''' ''' def __init__(self, wire, kbe_types=False): assert isinstance(wire, TopoDS_Wire), 'not a TopoDS_Wire' self.kbe_types = kbe_types self.wire = wire self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _reinitialize(self): self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _loop_topo(self, edges=True): if self.done: self._reinitialize() topologyType = TopoDS_edge if edges else TopoDS_vertex seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.wire_explorer.More(): # loop edges if edges: current_item = self.wire_explorer.Current() # loop vertices else: current_item = self.wire_explorer.CurrentVertex() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.wire_explorer.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = topologyType(occ_iterator.Value()) if self.kbe_types and edges: edge = Edge(topo_to_add) seq.append(edge) else: seq.append(topo_to_add) occ_iterator.Next() self.done = True return iter(seq) def ordered_edges(self): return self._loop_topo(edges=True) def ordered_vertices(self): return self._loop_topo(edges=False) class Topo(object): ''' Topology traversal ''' def __init__(self, myShape, kbe_types=False, ignore_orientation=False): """ implements topology traversal from any TopoDS_Shape this class lets you find how various topological entities are connected from one to another find the faces connected to an edge, find the vertices this edge is made from, get all faces connected to a vertex, and find out how many topological elements are connected from a source *note* when traversing TopoDS_Wire entities, its advised to use the specialized ``WireExplorer`` class, which will return the vertices / edges in the expected order :param myShape: the shape which topology will be traversed :param kbe_types: whether to return OCC.KBE topology types KBE types offers a more consistent and pythonic API, since many useful methods are bound to these objects :param ignore_orientation: filter out TopoDS_* entities of similar TShape but different Orientation for instance, a cube has 24 edges, 4 edges for each of 6 faces that results in 48 vertices, while there are only 8 vertices that have a unique geometric coordinate in certain cases ( computing a graph from the topology ) its preferable to return topological entities that share similar geometry, though differ in orientation by setting the ``ignore_orientation`` variable to True, in case of a cube, just 12 edges and only 8 vertices will be returned for further reference see TopoDS_Shape IsEqual / IsSame methods """ self.myShape = myShape self.kbe_types = kbe_types self.ignore_orientation = ignore_orientation self.topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid } if self.kbe_types: from OCC.KBE.vertex import Vertex from OCC.KBE.edge import Edge from OCC.KBE.face import Face from OCC.KBE.solid import Shell, Solid self.kbeTypes = { TopAbs_VERTEX: Vertex, TopAbs_EDGE: Edge, TopAbs_FACE: Face, TopAbs_SHELL: Shell, TopAbs_SOLID: Solid, } def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=None): ''' this could be a faces generator for a python TopoShape class that way you can just do: for face in srf.faces: processFace(face) ''' topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid} assert topologyType in topoTypes.keys(), '%s not one of %s' %( topologyType, topoTypes.keys() ) self.topExp = TopExp_Explorer() # use self.myShape if nothing is specified if topologicalEntity is None and topologyTypeToAvoid is None: self.topExp.Init(self.myShape, topologyType) elif topologicalEntity is None and topologyTypeToAvoid is not None: self.topExp.Init(self.myShape, topologyType, topologyTypeToAvoid) elif topologyTypeToAvoid is None: self.topExp.Init(topologicalEntity, topologyType ) elif topologyTypeToAvoid: self.topExp.Init(topologicalEntity, topologyType, topologyTypeToAvoid) topo_set = set() seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.topExp.More(): current_item = self.topExp.Current() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.topExp.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = self.topoTypes[topologyType](occ_iterator.Value()) # return a KBE type if self.kbe_types: if topologyType in self.kbeTypes: seq.append(self.kbeTypes[topologyType](topo_to_add)) # otherwise a plain TopoDS_Shape subclass else: seq.append(topo_to_add) occ_iterator.Next() if self.ignore_orientation: # filter out those entities that share the same TShape # but do *not* share the same orientation filter_orientation_seq = [] for i in seq: _present = False for j in filter_orientation_seq: if i.IsSame(j): _present = True break if _present is False: filter_orientation_seq.append(i) return filter_orientation_seq else: return iter(seq) def faces(self): ''' loops over all faces ''' return self._loop_topo(TopAbs_FACE) def _number_of_topo(self, iterable): n = 0 for i in iterable: n+=1 return n def number_of_faces(self): return self._number_of_topo(self.faces()) def vertices(self): ''' loops over all vertices ''' return self._loop_topo(TopAbs_VERTEX) def number_of_vertices(self): return self._number_of_topo(self.vertices()) def edges(self): ''' loops over all edges ''' return self._loop_topo(TopAbs_EDGE) def number_of_edges(self): return self._number_of_topo(self.edges()) def wires(self): ''' loops over all wires ''' return self._loop_topo(TopAbs_WIRE) def number_of_wires(self): return self._number_of_topo(self.wires()) def shells(self): ''' loops over all shells ''' return self._loop_topo(TopAbs_SHELL, None) def number_of_shells(self): return self._number_of_topo(self.shells()) def solids(self): ''' loops over all solids ''' return self._loop_topo(TopAbs_SOLID, None) def number_of_solids(self): return self._number_of_topo(self.solids()) def comp_solids(self): ''' loops over all compound solids ''' return self._loop_topo(TopAbs_COMPSOLID) def number_of_comp_solids(self): return self._number_of_topo(self.comp_solids()) def compounds(self): ''' loops over all compounds ''' return self._loop_topo(TopAbs_COMPOUND) def number_of_compounds(self): return self._number_of_topo(self.compounds()) def ordered_vertices_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_vertices() def number_of_ordered_vertices_from_wire(self, wire): return self._number_of_topo(self.ordered_vertices_from_wire(wire)) def ordered_edges_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_edges() def number_of_ordered_edges_from_wire(self, wire): return self._number_of_topo(self.ordered_edges_from_wire(wire)) def _map_shapes_and_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): ''' using the same method @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): yield None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_entity = self.topoTypes[topoTypeB](topology_iterator.Value()) if self.kbe_types: if topoTypeB in self.kbeTypes: topo_entity = self.kbeTypes[topoTypeB](topo_entity) else: raise ValueError('none KBE types called') # return the entity if not in set # to assure we're not returning entities several times if not topo_entity in topo_set: if self.ignore_orientation: unique=True for i in topo_set: if i.IsSame(topo_entity): unique=False break if unique: yield topo_entity else: yield topo_entity topo_set.add(topo_entity) topology_iterator.Next() def _number_shapes_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): '''returns the number of shape ancestors If you want to know how many edges a faces has: _number_shapes_ancestors(self, TopAbs_EDGE, TopAbs_FACE, edg) will return the number of edges a faces has @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): return None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_set.add(topology_iterator.Value()) topology_iterator.Next() return len(topo_set) #=============================================================================== # EDGE <-> FACE #=============================================================================== def faces_from_edge(self, edge): """ :param edge: :return: """ return self._map_shapes_and_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def number_of_faces_from_edge(self, edge): """ :param edge: :return: """ return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def edges_from_face(self, face): """ :param face: :return: """ return self._loop_topo(TopAbs_EDGE, face) def number_of_edges_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, face): cnt += 1 return cnt #=============================================================================== # VERTEX <-> EDGE #=============================================================================== def vertices_from_edge(self, edg): return self._loop_topo(TopAbs_VERTEX, edg) def number_of_vertices_from_edge(self, edg): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, edg): cnt += 1 return cnt def edges_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_EDGE,vertex) def number_of_edges_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_EDGE,vertex) #=============================================================================== # WIRE <-> EDGE #=============================================================================== def edges_from_wire(self, wire): return self._loop_topo(TopAbs_EDGE, wire) def number_of_edges_from_wire(self, wire): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, wire): cnt += 1 return cnt def wires_from_edge(self, edg): return self._map_shapes_and_ancestors(TopAbs_EDGE, TopAbs_WIRE, edg) def wires_from_vertex(self, edg): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_WIRE, edg) def number_of_wires_from_edge(self, edg): return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_WIRE, edg) #=============================================================================== # WIRE <-> FACE #=============================================================================== def wires_from_face(self, face): return self._loop_topo(TopAbs_WIRE, face) def number_of_wires_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_WIRE, face): cnt += 1 return cnt def faces_from_wire(self, wire): return self._map_shapes_and_ancestors(TopAbs_WIRE, TopAbs_FACE, wire) def number_of_faces_from_wires(self, wire): return self._number_shapes_ancestors(TopAbs_WIRE,TopAbs_FACE, wire) #=============================================================================== # VERTEX <-> FACE #=============================================================================== def faces_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def number_of_faces_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def vertices_from_face(self, face): return self._loop_topo(TopAbs_VERTEX, face) def number_of_vertices_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, face): cnt += 1 return cnt #=============================================================================== # FACE <-> SOLID #=============================================================================== def solids_from_face(self, face): return self._map_shapes_and_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def number_of_solids_from_face(self, face): return self._number_shapes_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def faces_from_solids(self, solid): return self._loop_topo(TopAbs_FACE, solid) def number_of_faces_from_solids(self, solid): cnt = 0 for i in self._loop_topo(TopAbs_FACE, solid): cnt += 1 return cnt def dump_topology(shape,level=0): """ Print the details of an object from the top down """ brt = BRep_Tool() s = shape.ShapeType() ts = TopoDS.TopoDS() print print "." * level,topo_lut[shape.ShapeType()], if s == TopAbs_VERTEX: pnt = vertex2pnt(shape_lut[shape]) print "" % (pnt.X(), pnt.Y(), pnt.Z()) it = TopoDS.TopoDS_Iterator(shape) while it.More(): shp = it.Value() it.Next() dump_topology(shp,level + 1 ) def shapeTypeString(shape): st = shape.ShapeType() s = "?" if st == TopAbs_VERTEX: s = "Vertex" if st == TopAbs_SOLID: s = "Solid" if st == TopAbs_EDGE: s = "Edge" if st == TopAbs_FACE: s = "Face" if st == TopAbs_SHELL: s = "Shell" if st == TopAbs_WIRE: s = "Wire" if st == TopAbs_COMPOUND: s = "Compound." if st == TopAbs_COMPSOLID: s = "Compsolid." return s + ":" + str(shape.HashCode(23232232)) \ No newline at end of file +# -*- coding: iso-8859-1 -*- #!/usr/bin/env python ##Copyright 2008-2011 Jelle Feringa (jelleferinga@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC 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 3 of the License, or ##(at your option) any later version. ## ##pythonOCC 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 pythonOCC. If not, see . ''' TODO: Hide WireExplorer... BRepTools.Map3DEdges() History: 20-01-2009: initial version 23-03-2009: completed and updated for modular pythonOCC build 23-04-2009: fixed a reference issue ( fixed using ReInit ) ''' from OCC.TopAbs import * from OCC.TopExp import * from OCC.TopoDS import * from OCC.TopTools import * from OCC.BRepTools import * from OCC.BRep import * from OCC.Utils.Construct import vertex2pnt import sys, itertools __all__ = ['Topo', 'WireExplorer'] class WireExplorer(object): ''' ''' def __init__(self, wire, kbe_types=False): assert isinstance(wire, TopoDS_Wire), 'not a TopoDS_Wire' self.kbe_types = kbe_types self.wire = wire self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _reinitialize(self): self.wire_explorer = BRepTools_WireExplorer(self.wire) self.done = False def _loop_topo(self, edges=True): if self.done: self._reinitialize() topologyType = TopoDS_edge if edges else TopoDS_vertex seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.wire_explorer.More(): # loop edges if edges: current_item = self.wire_explorer.Current() # loop vertices else: current_item = self.wire_explorer.CurrentVertex() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.wire_explorer.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = topologyType(occ_iterator.Value()) if self.kbe_types and edges: edge = Edge(topo_to_add) seq.append(edge) else: seq.append(topo_to_add) occ_iterator.Next() self.done = True return iter(seq) def ordered_edges(self): return self._loop_topo(edges=True) def ordered_vertices(self): return self._loop_topo(edges=False) class Topo(object): ''' Topology traversal ''' def __init__(self, myShape, kbe_types=False, ignore_orientation=False): """ implements topology traversal from any TopoDS_Shape this class lets you find how various topological entities are connected from one to another find the faces connected to an edge, find the vertices this edge is made from, get all faces connected to a vertex, and find out how many topological elements are connected from a source *note* when traversing TopoDS_Wire entities, its advised to use the specialized ``WireExplorer`` class, which will return the vertices / edges in the expected order :param myShape: the shape which topology will be traversed :param kbe_types: whether to return OCC.KBE topology types KBE types offers a more consistent and pythonic API, since many useful methods are bound to these objects :param ignore_orientation: filter out TopoDS_* entities of similar TShape but different Orientation for instance, a cube has 24 edges, 4 edges for each of 6 faces that results in 48 vertices, while there are only 8 vertices that have a unique geometric coordinate in certain cases ( computing a graph from the topology ) its preferable to return topological entities that share similar geometry, though differ in orientation by setting the ``ignore_orientation`` variable to True, in case of a cube, just 12 edges and only 8 vertices will be returned for further reference see TopoDS_Shape IsEqual / IsSame methods """ self.myShape = myShape self.kbe_types = kbe_types self.ignore_orientation = ignore_orientation self.topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid } if self.kbe_types: from OCC.KBE.types_lut import topo_lut, shape_lut from OCC.KBE.vertex import Vertex from OCC.KBE.edge import Edge from OCC.KBE.face import Face from OCC.KBE.solid import Shell, Solid self.kbeTypes = { TopAbs_VERTEX: Vertex, TopAbs_EDGE: Edge, TopAbs_FACE: Face, TopAbs_SHELL: Shell, TopAbs_SOLID: Solid, } def _loop_topo(self, topologyType, topologicalEntity=None, topologyTypeToAvoid=None): ''' this could be a faces generator for a python TopoShape class that way you can just do: for face in srf.faces: processFace(face) ''' topoTypes = { TopAbs_VERTEX: TopoDS_vertex, TopAbs_EDGE: TopoDS_edge, TopAbs_FACE: TopoDS_face, TopAbs_WIRE: TopoDS_wire, TopAbs_SHELL: TopoDS_shell, TopAbs_SOLID: TopoDS_solid, TopAbs_COMPOUND: TopoDS_compound, TopAbs_COMPSOLID: TopoDS_compsolid} assert topologyType in topoTypes.keys(), '%s not one of %s' %( topologyType, topoTypes.keys() ) self.topExp = TopExp_Explorer() # use self.myShape if nothing is specified if topologicalEntity is None and topologyTypeToAvoid is None: self.topExp.Init(self.myShape, topologyType) elif topologicalEntity is None and topologyTypeToAvoid is not None: self.topExp.Init(self.myShape, topologyType, topologyTypeToAvoid) elif topologyTypeToAvoid is None: self.topExp.Init(topologicalEntity, topologyType ) elif topologyTypeToAvoid: self.topExp.Init(topologicalEntity, topologyType, topologyTypeToAvoid) topo_set = set() seq = [] hashes = [] #list that stores hashes to avoid redundancy occ_seq = TopTools_ListOfShape() while self.topExp.More(): current_item = self.topExp.Current() current_item_hash = current_item.__hash__() if not current_item_hash in hashes: hashes.append(current_item_hash) occ_seq.Append(current_item) self.topExp.Next() # Convert occ_seq to python list occ_iterator = TopTools_ListIteratorOfListOfShape(occ_seq) while occ_iterator.More(): topo_to_add = self.topoTypes[topologyType](occ_iterator.Value()) # return a KBE type if self.kbe_types: if topologyType in self.kbeTypes: seq.append(self.kbeTypes[topologyType](topo_to_add)) # otherwise a plain TopoDS_Shape subclass else: seq.append(topo_to_add) occ_iterator.Next() if self.ignore_orientation: # filter out those entities that share the same TShape # but do *not* share the same orientation filter_orientation_seq = [] for i in seq: _present = False for j in filter_orientation_seq: if i.IsSame(j): _present = True break if _present is False: filter_orientation_seq.append(i) return filter_orientation_seq else: return iter(seq) def faces(self): ''' loops over all faces ''' return self._loop_topo(TopAbs_FACE) def _number_of_topo(self, iterable): n = 0 for i in iterable: n+=1 return n def number_of_faces(self): return self._number_of_topo(self.faces()) def vertices(self): ''' loops over all vertices ''' return self._loop_topo(TopAbs_VERTEX) def number_of_vertices(self): return self._number_of_topo(self.vertices()) def edges(self): ''' loops over all edges ''' return self._loop_topo(TopAbs_EDGE) def number_of_edges(self): return self._number_of_topo(self.edges()) def wires(self): ''' loops over all wires ''' return self._loop_topo(TopAbs_WIRE) def number_of_wires(self): return self._number_of_topo(self.wires()) def shells(self): ''' loops over all shells ''' return self._loop_topo(TopAbs_SHELL, None) def number_of_shells(self): return self._number_of_topo(self.shells()) def solids(self): ''' loops over all solids ''' return self._loop_topo(TopAbs_SOLID, None) def number_of_solids(self): return self._number_of_topo(self.solids()) def comp_solids(self): ''' loops over all compound solids ''' return self._loop_topo(TopAbs_COMPSOLID) def number_of_comp_solids(self): return self._number_of_topo(self.comp_solids()) def compounds(self): ''' loops over all compounds ''' return self._loop_topo(TopAbs_COMPOUND) def number_of_compounds(self): return self._number_of_topo(self.compounds()) def ordered_vertices_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_vertices() def number_of_ordered_vertices_from_wire(self, wire): return self._number_of_topo(self.ordered_vertices_from_wire(wire)) def ordered_edges_from_wire(self, wire): ''' @param wire: TopoDS_Wire ''' we = WireExplorer(wire) return we.ordered_edges() def number_of_ordered_edges_from_wire(self, wire): return self._number_of_topo(self.ordered_edges_from_wire(wire)) def _map_shapes_and_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): ''' using the same method @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): yield None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_entity = self.topoTypes[topoTypeB](topology_iterator.Value()) if self.kbe_types: if topoTypeB in self.kbeTypes: topo_entity = self.kbeTypes[topoTypeB](topo_entity) else: raise ValueError('none KBE types called') # return the entity if not in set # to assure we're not returning entities several times if not topo_entity in topo_set: if self.ignore_orientation: unique=True for i in topo_set: if i.IsSame(topo_entity): unique=False break if unique: yield topo_entity else: yield topo_entity topo_set.add(topo_entity) topology_iterator.Next() def _number_shapes_ancestors(self, topoTypeA, topoTypeB, topologicalEntity): '''returns the number of shape ancestors If you want to know how many edges a faces has: _number_shapes_ancestors(self, TopAbs_EDGE, TopAbs_FACE, edg) will return the number of edges a faces has @param topoTypeA: @param topoTypeB: @param topologicalEntity: ''' topo_set = set() _map = TopTools_IndexedDataMapOfShapeListOfShape() TopExp_MapShapesAndAncestors(self.myShape, topoTypeA, topoTypeB, _map) results = _map.FindFromKey(topologicalEntity) if results.IsEmpty(): return None topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): topo_set.add(topology_iterator.Value()) topology_iterator.Next() return len(topo_set) #=============================================================================== # EDGE <-> FACE #=============================================================================== def faces_from_edge(self, edge): """ :param edge: :return: """ return self._map_shapes_and_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def number_of_faces_from_edge(self, edge): """ :param edge: :return: """ return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_FACE,edge) def edges_from_face(self, face): """ :param face: :return: """ return self._loop_topo(TopAbs_EDGE, face) def number_of_edges_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, face): cnt += 1 return cnt #=============================================================================== # VERTEX <-> EDGE #=============================================================================== def vertices_from_edge(self, edg): return self._loop_topo(TopAbs_VERTEX, edg) def number_of_vertices_from_edge(self, edg): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, edg): cnt += 1 return cnt def edges_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_EDGE,vertex) def number_of_edges_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_EDGE,vertex) #=============================================================================== # WIRE <-> EDGE #=============================================================================== def edges_from_wire(self, wire): return self._loop_topo(TopAbs_EDGE, wire) def number_of_edges_from_wire(self, wire): cnt = 0 for i in self._loop_topo(TopAbs_EDGE, wire): cnt += 1 return cnt def wires_from_edge(self, edg): return self._map_shapes_and_ancestors(TopAbs_EDGE, TopAbs_WIRE, edg) def wires_from_vertex(self, edg): return self._map_shapes_and_ancestors(TopAbs_VERTEX, TopAbs_WIRE, edg) def number_of_wires_from_edge(self, edg): return self._number_shapes_ancestors(TopAbs_EDGE,TopAbs_WIRE, edg) #=============================================================================== # WIRE <-> FACE #=============================================================================== def wires_from_face(self, face): return self._loop_topo(TopAbs_WIRE, face) def number_of_wires_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_WIRE, face): cnt += 1 return cnt def faces_from_wire(self, wire): return self._map_shapes_and_ancestors(TopAbs_WIRE, TopAbs_FACE, wire) def number_of_faces_from_wires(self, wire): return self._number_shapes_ancestors(TopAbs_WIRE,TopAbs_FACE, wire) #=============================================================================== # VERTEX <-> FACE #=============================================================================== def faces_from_vertex(self, vertex): return self._map_shapes_and_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def number_of_faces_from_vertex(self, vertex): return self._number_shapes_ancestors(TopAbs_VERTEX,TopAbs_FACE,vertex) def vertices_from_face(self, face): return self._loop_topo(TopAbs_VERTEX, face) def number_of_vertices_from_face(self, face): cnt = 0 for i in self._loop_topo(TopAbs_VERTEX, face): cnt += 1 return cnt #=============================================================================== # FACE <-> SOLID #=============================================================================== def solids_from_face(self, face): return self._map_shapes_and_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def number_of_solids_from_face(self, face): return self._number_shapes_ancestors(TopAbs_FACE,TopAbs_SOLID,face) def faces_from_solids(self, solid): return self._loop_topo(TopAbs_FACE, solid) def number_of_faces_from_solids(self, solid): cnt = 0 for i in self._loop_topo(TopAbs_FACE, solid): cnt += 1 return cnt def dump_topology(shape,level=0): """ Print the details of an object from the top down """ brt = BRep_Tool() s = shape.ShapeType() ts = TopoDS.TopoDS() print print "." * level,topo_lut[shape.ShapeType()], if s == TopAbs_VERTEX: pnt = vertex2pnt(shape_lut[shape]) print "" % (pnt.X(), pnt.Y(), pnt.Z()) it = TopoDS.TopoDS_Iterator(shape) while it.More(): shp = it.Value() it.Next() dump_topology(shp,level + 1 ) def shapeTypeString(shape): st = shape.ShapeType() s = "?" if st == TopAbs_VERTEX: s = "Vertex" if st == TopAbs_SOLID: s = "Solid" if st == TopAbs_EDGE: s = "Edge" if st == TopAbs_FACE: s = "Face" if st == TopAbs_SHELL: s = "Shell" if st == TopAbs_WIRE: s = "Wire" if st == TopAbs_COMPOUND: s = "Compound." if st == TopAbs_COMPSOLID: s = "Compsolid." return s + ":" + str(shape.HashCode(23232232)) \ No newline at end of file diff --git a/src/contrib/smesh-5.1.2.2/inc/SMESH_MeshVSLink.hxx b/src/contrib/smesh-5.1.2.2/inc/SMESH_MeshVSLink.hxx index 9c1123d3a..d4f6962d4 100755 --- a/src/contrib/smesh-5.1.2.2/inc/SMESH_MeshVSLink.hxx +++ b/src/contrib/smesh-5.1.2.2/inc/SMESH_MeshVSLink.hxx @@ -1,27 +1,27 @@ // SMESH SMESH_MeshVSLink : Connection of SMESH with MeshVS from OCC -// -// Copyright (C) 2003 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. -// -// 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 : SMESH_MeshVSLink.cxx -// Created : Mon Dec 1 09:00:00 2008 -// Author : Sioutis Fotios +// +// Copyright (C) 2003 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. +// +// 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 : SMESH_MeshVSLink.cxx +// Created : Mon Dec 1 09:00:00 2008 +// Author : Sioutis Fotios // Module : SMESH #ifndef _SMESH_MeshVSLink_HeaderFile @@ -75,11 +75,14 @@ class SMESH_MeshVSLink : public MeshVS_DataSource3D { //! Constructor
Standard_EXPORT SMESH_MeshVSLink(const SMESH_Mesh *aMesh); + Standard_EXPORT Standard_Boolean GetNodeNormal(const Standard_Integer ranknode,const Standard_Integer ElementId,Standard_Real& nx,Standard_Real& ny,Standard_Real& nz) const; //Not implemented yet /* - Standard_EXPORT Standard_Boolean GetNodeNormal(const Standard_Integer ranknode,const Standard_Integer ElementId,Standard_Real& nx,Standard_Real& ny,Standard_Real& nz) const; + + + Standard_EXPORT Standard_Boolean GetNormalsByElement(const Standard_Integer Id,const Standard_Boolean IsNodal,const Standard_Integer MaxNodes,Handle(TColStd_HArray1OfReal)& Normals) const; Standard_EXPORT void GetAllGroups(TColStd_PackedMapOfInteger& Ids) const; Standard_EXPORT Standard_Boolean GetGroup(const Standard_Integer Id,MeshVS_EntityType& Type,TColStd_PackedMapOfInteger& Ids) const; diff --git a/src/contrib/smesh-5.1.2.2/src/SMESH/SMESH_MeshVSLink.cpp b/src/contrib/smesh-5.1.2.2/src/SMESH/SMESH_MeshVSLink.cpp index 0f3991aa0..dd560598c 100755 --- a/src/contrib/smesh-5.1.2.2/src/SMESH/SMESH_MeshVSLink.cpp +++ b/src/contrib/smesh-5.1.2.2/src/SMESH/SMESH_MeshVSLink.cpp @@ -1,4 +1,4 @@ -// SMESH SMESH_MeshVSLink : Connection of SMESH with MeshVS from OCC +// SMESH SMESH_MeshVSLink : Connection of SMESH with MeshVS from OCC // // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -22,29 +22,29 @@ // File : SMESH_MeshVSLink.cxx // Created : Mon Dec 1 09:00:00 2008 // Author : Sioutis Fotios -// Module : SMESH - -//local headers -#include -#include - -//occ headers -#include -#include -#include - -//BEGIN sortNodes CHANGE /* -#include - -#include -#include -#include - -#define MAX_SORT_NODE_COUNT 12 - -typedef std::map T_Double_NodeID_Map; - -//======================================================================= +// Module : SMESH + +//local headers +#include +#include + +//occ headers +#include +#include +#include + +//BEGIN sortNodes CHANGE /* +#include + +#include +#include +#include + +#define MAX_SORT_NODE_COUNT 12 + +typedef std::map T_Double_NodeID_Map; + +//======================================================================= //function : sortNodes //purpose : //======================================================================= @@ -88,47 +88,53 @@ bool sortNodes (const SMDS_MeshElement* theTool, const int* idNodes, int theNode myMap.insert( make_pair(myAngleList.Value(i), idNodes[i-1])); int resID = 0; T_Double_NodeID_Map::iterator it; - for(it = myMap.begin(); it!= myMap.end(); ++it) + for(it = myMap.begin(); it!= myMap.end(); ++it) myResult[resID++] = it->second; return true; -} -//END sortNodes CHANGE */ - -//================================================================ -// Function : Constructor -// Purpose : -//================================================================ -SMESH_MeshVSLink::SMESH_MeshVSLink(const SMESH_Mesh *aMesh) -{ - myMesh = (SMESH_Mesh*) aMesh; - //add the nodes - SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); - for(;aNodeIter->more();) { +} +//END sortNodes CHANGE */ + +//================================================================ +// Function : Constructor +// Purpose : +//================================================================ +SMESH_MeshVSLink::SMESH_MeshVSLink(const SMESH_Mesh *aMesh) +{ + myMesh = (SMESH_Mesh*) aMesh; + //add the nodes + SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); + for(;aNodeIter->more();) { const SMDS_MeshNode* aNode = aNodeIter->next(); myNodes.Add( aNode->GetID() ); - } - //add the edges - SMDS_EdgeIteratorPtr anEdgeIter = myMesh->GetMeshDS()->edgesIterator(); + } + //add the edges + SMDS_EdgeIteratorPtr anEdgeIter = myMesh->GetMeshDS()->edgesIterator(); for(;anEdgeIter->more();) { const SMDS_MeshEdge* anElem = anEdgeIter->next(); myElements.Add( anElem->GetID() ); - } - //add the faces - SMDS_FaceIteratorPtr aFaceIter = myMesh->GetMeshDS()->facesIterator(); + } + //add the faces + SMDS_FaceIteratorPtr aFaceIter = myMesh->GetMeshDS()->facesIterator(); for(;aFaceIter->more();) { const SMDS_MeshFace* anElem = aFaceIter->next(); myElements.Add( anElem->GetID() ); } - //add the volumes - SMDS_VolumeIteratorPtr aVolumeIter = myMesh->GetMeshDS()->volumesIterator(); - for(;aVolumeIter->more();) { + + //add the volumes + + SMDS_VolumeIteratorPtr aVolumeIter = myMesh->GetMeshDS()->volumesIterator(); + + for(;aVolumeIter->more();) { const SMDS_MeshVolume* anElem = aVolumeIter->next(); myElements.Add( anElem->GetID() ); } - //add the groups - const std::set& groups = myMesh->GetMeshDS()->GetGroups(); - if (!groups.empty()) { + + //add the groups + + const std::set& groups = myMesh->GetMeshDS()->GetGroups(); + + if (!groups.empty()) { std::set::const_iterator GrIt = groups.begin(); for (; GrIt != groups.end(); GrIt++) { SMESHDS_Group* grp = dynamic_cast(*GrIt); @@ -136,195 +142,212 @@ SMESH_MeshVSLink::SMESH_MeshVSLink(const SMESH_Mesh *aMesh) myGroups.Add(grp->GetID()); } } - } - -//================================================================ -// Function : GetGeom -// Purpose : -//================================================================ -Standard_Boolean SMESH_MeshVSLink::GetGeom - ( const Standard_Integer ID, const Standard_Boolean IsElement, - TColStd_Array1OfReal& Coords, Standard_Integer& NbNodes, - MeshVS_EntityType& Type ) const -{ - if( IsElement ) { - const SMDS_MeshElement* myElem = myMesh->GetMeshDS()->FindElement(ID); - if (!myElem) return Standard_False; - if (myElem->GetType() == SMDSAbs_Edge) - Type = MeshVS_ET_Link; - else if (myElem->GetType() == SMDSAbs_Face) - Type = MeshVS_ET_Face; - else if (myElem->GetType() == SMDSAbs_Volume) - Type = MeshVS_ET_Volume; - else - Type = MeshVS_ET_Element; - NbNodes = myElem->NbNodes(); - int nbCoord = 1; - for(Standard_Integer i = 0; i < NbNodes; i++ ) { - Coords(nbCoord++) = myElem->GetNode(i)->X(); - Coords(nbCoord++) = myElem->GetNode(i)->Y(); - Coords(nbCoord++) = myElem->GetNode(i)->Z(); - } - } - else { - const SMDS_MeshNode* myNode = myMesh->GetMeshDS()->FindNode(ID); - if (!myNode) return Standard_False; - if (myNode->GetType() == SMDSAbs_Node) - Type = MeshVS_ET_Node; - else - Type = MeshVS_ET_0D; - NbNodes = 1; - Coords(1) = myNode->X(); - Coords(2) = myNode->Y(); - Coords(3) = myNode->Z(); - } - return Standard_True; -} - -//================================================================ -// Function : Get3DGeom -// Purpose : -//================================================================ -Standard_Boolean SMESH_MeshVSLink::Get3DGeom - ( const Standard_Integer ID, Standard_Integer& NbNodes, - Handle(MeshVS_HArray1OfSequenceOfInteger)& Data) const -{ - //check validity of element - const SMDS_MeshElement* myVolume = myMesh->GetMeshDS()->FindElement(ID); - if (!myVolume) return Standard_False; - if (myVolume->GetType() != SMDSAbs_Volume) return Standard_False; - - //initialize VolumeTool - SMDS_VolumeTool aTool; - aTool.Set(myVolume); - //set the nodes number - NbNodes = aTool.NbNodes();// myVolume->NbNodes(); - //check validity or create Data - int NbFaces = aTool.NbFaces(); - if (Data.IsNull()) - Data = new MeshVS_HArray1OfSequenceOfInteger(1, NbFaces); - else if (Data->Length() != NbFaces) { - Data.Nullify(); - Data = new MeshVS_HArray1OfSequenceOfInteger(1, NbFaces); - } - //iterate the faces and their nodes and add them to Data - for (int itr=0;itr < NbFaces;itr++) { - int NbThisFaceNodeCount = aTool.NbFaceNodes(itr); - const int *FaceIndices = aTool.GetFaceNodesIndices(itr); - int sortedFaceIndices[MAX_SORT_NODE_COUNT]; - TColStd_SequenceOfInteger aSeq; - if (sortNodes(myVolume, FaceIndices, NbThisFaceNodeCount, sortedFaceIndices)) { - for (int itrX=0;itrX < NbThisFaceNodeCount;itrX++) - aSeq.Append(sortedFaceIndices[itrX]); - } else { - for (int itrX=0;itrX < NbThisFaceNodeCount;itrX++) - aSeq.Append(FaceIndices[itrX]); - } - Data->SetValue(itr+1, aSeq); - } - return Standard_True; -} - -//================================================================ -// Function : GetGeomType -// Purpose : -//================================================================ -Standard_Boolean SMESH_MeshVSLink::GetGeomType - ( const Standard_Integer ID, - const Standard_Boolean IsElement, - MeshVS_EntityType& Type ) const -{ - if( IsElement ) { - const SMDS_MeshElement* myElem = myMesh->GetMeshDS()->FindElement(ID); - if (!myElem) return Standard_False; - if (myElem->GetType() == SMDSAbs_Edge) - Type = MeshVS_ET_Link; - else if (myElem->GetType() == SMDSAbs_Face) - Type = MeshVS_ET_Face; - else if (myElem->GetType() == SMDSAbs_Volume) - Type = MeshVS_ET_Volume; - else - Type = MeshVS_ET_Element; - } - else { - const SMDS_MeshNode* myNode = myMesh->GetMeshDS()->FindNode(ID); - if (!myNode) return Standard_False; - if (myNode->GetType() == SMDSAbs_Node) - Type = MeshVS_ET_Node; - else - Type = MeshVS_ET_0D; - } - return Standard_True; -} - -//================================================================ -// Function : GetAddr -// Purpose : -//================================================================ -Standard_Address SMESH_MeshVSLink::GetAddr - ( const Standard_Integer, const Standard_Boolean ) const -{ - return NULL; -} - -//================================================================ -// Function : GetNodesByElement -// Purpose : -//================================================================ -Standard_Boolean SMESH_MeshVSLink::GetNodesByElement - ( const Standard_Integer ID,TColStd_Array1OfInteger& NodeIDs,Standard_Integer& NbNodes ) const -{ - const SMDS_MeshElement* myElem = myMesh->GetMeshDS()->FindElement(ID); - if (!myElem) return Standard_False; - NbNodes = myElem->NbNodes(); - for(Standard_Integer i = 0; i < NbNodes; i++ ) { - const SMDS_MeshNode* aNode = myElem->GetNode(i); - if (!aNode) return Standard_False; - NodeIDs.SetValue(i+1, aNode->GetID()); - } - return Standard_True; -} - -//================================================================ -// Function : GetAllNodes -// Purpose : -//================================================================ -const TColStd_PackedMapOfInteger& SMESH_MeshVSLink::GetAllNodes() const -{ - return myNodes; -} - -//================================================================ -// Function : GetAllElements -// Purpose : -//================================================================ -const TColStd_PackedMapOfInteger& SMESH_MeshVSLink::GetAllElements() const -{ - return myElements; -} - -//================================================================ -// Function : GetAllElements -// Purpose : -//================================================================ -void SMESH_MeshVSLink::GetAllGroups(TColStd_PackedMapOfInteger& Ids) const -{ - Ids = myGroups; -} - -//================================================================ -// Function : GetNormal -// Purpose : -//================================================================ -Standard_Boolean SMESH_MeshVSLink::GetNormal - ( const Standard_Integer Id, const Standard_Integer Max, - Standard_Real& nx, Standard_Real& ny,Standard_Real& nz ) const -{ - if(Max<3) return Standard_False; - const SMDS_MeshElement* myElem = myMesh->GetMeshDS()->FindElement(Id); - if(!myElem) return Standard_False; - if(myElem->NbNodes() < 3) return Standard_False; - gp_XYZ normal; + +} + +//================================================================ +// Function : GetGeom +// Purpose : +//================================================================ +Standard_Boolean SMESH_MeshVSLink::GetGeom + ( const Standard_Integer ID, const Standard_Boolean IsElement, + TColStd_Array1OfReal& Coords, Standard_Integer& NbNodes, + MeshVS_EntityType& Type ) const +{ + if( IsElement ) { + const SMDS_MeshElement* myElem = myMesh->GetMeshDS()->FindElement(ID); + if (!myElem) return Standard_False; + if (myElem->GetType() == SMDSAbs_Edge) + Type = MeshVS_ET_Link; + else if (myElem->GetType() == SMDSAbs_Face) + Type = MeshVS_ET_Face; + else if (myElem->GetType() == SMDSAbs_Volume) + Type = MeshVS_ET_Volume; + else + Type = MeshVS_ET_Element; + NbNodes = myElem->NbNodes(); + int nbCoord = 1; + for(Standard_Integer i = 0; i < NbNodes; i++ ) { + Coords(nbCoord++) = myElem->GetNode(i)->X(); + Coords(nbCoord++) = myElem->GetNode(i)->Y(); + Coords(nbCoord++) = myElem->GetNode(i)->Z(); + } + } + else { + const SMDS_MeshNode* myNode = myMesh->GetMeshDS()->FindNode(ID); + if (!myNode) return Standard_False; + if (myNode->GetType() == SMDSAbs_Node) + Type = MeshVS_ET_Node; + else + Type = MeshVS_ET_0D; + NbNodes = 1; + Coords(1) = myNode->X(); + Coords(2) = myNode->Y(); + Coords(3) = myNode->Z(); + } + return Standard_True; +} + +//================================================================ +// Function : Get3DGeom +// Purpose : +//================================================================ +Standard_Boolean SMESH_MeshVSLink::Get3DGeom + ( const Standard_Integer ID, Standard_Integer& NbNodes, + Handle(MeshVS_HArray1OfSequenceOfInteger)& Data) const +{ + //check validity of element + const SMDS_MeshElement* myVolume = myMesh->GetMeshDS()->FindElement(ID); + if (!myVolume) return Standard_False; + if (myVolume->GetType() != SMDSAbs_Volume) return Standard_False; + + //initialize VolumeTool + SMDS_VolumeTool aTool; + aTool.Set(myVolume); + //set the nodes number + NbNodes = aTool.NbNodes();// myVolume->NbNodes(); + //check validity or create Data + int NbFaces = aTool.NbFaces(); + if (Data.IsNull()) + Data = new MeshVS_HArray1OfSequenceOfInteger(1, NbFaces); + else if (Data->Length() != NbFaces) { + Data.Nullify(); + Data = new MeshVS_HArray1OfSequenceOfInteger(1, NbFaces); + } + //iterate the faces and their nodes and add them to Data + for (int itr=0;itr < NbFaces;itr++) { + int NbThisFaceNodeCount = aTool.NbFaceNodes(itr); + const int *FaceIndices = aTool.GetFaceNodesIndices(itr); + int sortedFaceIndices[MAX_SORT_NODE_COUNT]; + TColStd_SequenceOfInteger aSeq; + if (sortNodes(myVolume, FaceIndices, NbThisFaceNodeCount, sortedFaceIndices)) { + for (int itrX=0;itrX < NbThisFaceNodeCount;itrX++) + aSeq.Append(sortedFaceIndices[itrX]); + } else { + for (int itrX=0;itrX < NbThisFaceNodeCount;itrX++) + aSeq.Append(FaceIndices[itrX]); + } + Data->SetValue(itr+1, aSeq); + } + return Standard_True; +} + +//================================================================ +// Function : GetGeomType +// Purpose : +//================================================================ +Standard_Boolean SMESH_MeshVSLink::GetGeomType + ( const Standard_Integer ID, + const Standard_Boolean IsElement, + MeshVS_EntityType& Type ) const +{ + if( IsElement ) { + const SMDS_MeshElement* myElem = myMesh->GetMeshDS()->FindElement(ID); + if (!myElem) return Standard_False; + if (myElem->GetType() == SMDSAbs_Edge) + Type = MeshVS_ET_Link; + else if (myElem->GetType() == SMDSAbs_Face) + Type = MeshVS_ET_Face; + else if (myElem->GetType() == SMDSAbs_Volume) + Type = MeshVS_ET_Volume; + else + Type = MeshVS_ET_Element; + } + else { + const SMDS_MeshNode* myNode = myMesh->GetMeshDS()->FindNode(ID); + if (!myNode) return Standard_False; + if (myNode->GetType() == SMDSAbs_Node) + Type = MeshVS_ET_Node; + else + Type = MeshVS_ET_0D; + } + return Standard_True; +} + +//================================================================ +// Function : GetAddr +// Purpose : +//================================================================ +Standard_Address SMESH_MeshVSLink::GetAddr + ( const Standard_Integer, const Standard_Boolean ) const +{ + return NULL; +} + +// patches from Mark Blome + +//Standard_Boolean SMESH_MeshVSLink::GetNodeNormal( const Standard_Integer ranknode, const Standard_Integer Id, Standard_Real &nx, Standard_Real &ny, Standard_Real &nz) const +//{ +// return myElements.GetNodeNormal(ranknode-1, Id, nx, ny, nz); +//} +// +//Standard_Boolean SMESH_MeshVSLink::GetNormal( const Standard_Integer Id, const Standard_Integer Max, +// Standard_Real& nx, Standard_Real& ny,Standard_Real& nz ) const +//{ +// if(Max<3) return Standard_False; +// return myElements.GetNormal(Id, nx, ny, nz); +//} + + +//================================================================ +// Function : GetNodesByElement +// Purpose : +//================================================================ +Standard_Boolean SMESH_MeshVSLink::GetNodesByElement + ( const Standard_Integer ID,TColStd_Array1OfInteger& NodeIDs,Standard_Integer& NbNodes ) const +{ + const SMDS_MeshElement* myElem = myMesh->GetMeshDS()->FindElement(ID); + if (!myElem) return Standard_False; + NbNodes = myElem->NbNodes(); + for(Standard_Integer i = 0; i < NbNodes; i++ ) { + const SMDS_MeshNode* aNode = myElem->GetNode(i); + if (!aNode) return Standard_False; + NodeIDs.SetValue(i+1, aNode->GetID()); + } + return Standard_True; +} + +//================================================================ +// Function : GetAllNodes +// Purpose : +//================================================================ +const TColStd_PackedMapOfInteger& SMESH_MeshVSLink::GetAllNodes() const +{ + return myNodes; +} + +//================================================================ +// Function : GetAllElements +// Purpose : +//================================================================ +const TColStd_PackedMapOfInteger& SMESH_MeshVSLink::GetAllElements() const +{ + return myElements; +} + +//================================================================ +// Function : GetAllElements +// Purpose : +//================================================================ +void SMESH_MeshVSLink::GetAllGroups(TColStd_PackedMapOfInteger& Ids) const +{ + Ids = myGroups; +} + + +//================================================================ +// Function : GetNormal +// Purpose : +//================================================================ +Standard_Boolean SMESH_MeshVSLink::GetNormal + ( const Standard_Integer Id, const Standard_Integer Max, + Standard_Real& nx, Standard_Real& ny,Standard_Real& nz ) const +{ + if(Max<3) return Standard_False; + const SMDS_MeshElement* myElem = myMesh->GetMeshDS()->FindElement(Id); + if(!myElem) return Standard_False; + if(myElem->NbNodes() < 3) return Standard_False; + gp_XYZ normal; gp_XYZ nodes[3]; for (int itr = 0;itr < 3;itr++) nodes[itr] = gp_XYZ(myElem->GetNode(itr)->X(), myElem->GetNode(itr)->Y(), myElem->GetNode(itr)->Z()); @@ -334,5 +357,5 @@ Standard_Boolean SMESH_MeshVSLink::GetNormal nx = normal.X(); ny = normal.Y(); nz = normal.Z(); - return Standard_True; -} + return Standard_True; +} diff --git a/src/examples/DYN/dyn_demo.py b/src/examples/DYN/dyn_demo.py index a4e1ed53e..e039c29f8 100644 --- a/src/examples/DYN/dyn_demo.py +++ b/src/examples/DYN/dyn_demo.py @@ -311,7 +311,8 @@ def hinge(event=None): display.EraseAll() # Create the dynamic context dyn_context = DynamicSimulationContext() - dyn_context.set_display(display, safe_yield) + dyn_context.set_display(display, None) + # dyn_context.set_display(display, safe_yield) dyn_context.enable_collision_detection() dyn_context.enable_gravity() # create the table @@ -386,7 +387,8 @@ def adhesion(event=None): display.EraseAll() # Create the dynamic context dyn_context = DynamicSimulationContext() - dyn_context.set_display(display, safe_yield) + # dyn_context.set_display(display, safe_yield) + dyn_context.set_display(display, None) dyn_context.enable_collision_detection() dyn_context.enable_gravity() # create the table @@ -464,5 +466,5 @@ def exit(event=None): add_function_to_menu('rigid body simulation sample', collisions) add_function_to_menu('rigid body simulation sample', hinge) add_function_to_menu('rigid body simulation sample', adhesion) - adhesion() + # adhesion() start_display() diff --git a/src/examples/GEOM/partition.py b/src/examples/GEOM/partition.py index 76e939721..075b02793 100644 --- a/src/examples/GEOM/partition.py +++ b/src/examples/GEOM/partition.py @@ -3,7 +3,7 @@ import functools from OCC.Utils.Construct import * -from OCC.Partition import * +from OCC import Partition from OCC.TopAbs import * from OCC.TopoDS import * from OCC.Utils.Topology import Topo @@ -30,16 +30,22 @@ f1 = make_face(pl1) f2 = make_face(pl2) +disp = Display() +disp.display.DisplayShape([f1,f2]) +disp.display.FitAll() +disp.start_display() + +import ipdb; ipdb.set_trace() -spl = Partition_Spliter() + +spl = Partition.Partition_Spliter() spl.AddShape(f1) spl.AddTool(f2) -spl.Compute(TopAbs_SHAPE) +spl.Compute() shp = spl.Shape() shp = translate_topods_from_vector(shp, gp_Vec(30,0,0)) -disp = Display() tp = Topo(shp) From 4a5cd9cc100e0b770761ee377f0272a5fdfd1a8d Mon Sep 17 00:00:00 2001 From: jf--- Date: Sat, 4 Jan 2014 17:07:34 +0100 Subject: [PATCH 21/29] support for colors in DisplayVector and DisplayMessage --- src/addons/Display/OCCViewer.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/addons/Display/OCCViewer.py b/src/addons/Display/OCCViewer.py index 47d846844..c43bb81b9 100644 --- a/src/addons/Display/OCCViewer.py +++ b/src/addons/Display/OCCViewer.py @@ -49,6 +49,9 @@ def set_CSF_GraphicShr(): modes = itertools.cycle([TopAbs.TopAbs_FACE, TopAbs.TopAbs_EDGE, TopAbs.TopAbs_VERTEX, TopAbs.TopAbs_SHELL, TopAbs.TopAbs_SOLID, ]) +def get_color_name(color): + return color.Name(color.Red(), color.Green(), color.Blue()) + class BaseDriver(object): """ The base driver class @@ -180,10 +183,12 @@ def SetBackgroundImage(self, filename, Stretch = True): else: self.View.SetBackgroundImage(filename, OCC.Aspect.Aspect_FM_NONE, True ) - def DisplayVector(self, vec, pnt, update=False): + def DisplayVector(self, vec, pnt, update=False, veccolor=None): if self._inited: aPresentation = Prs3d.Prs3d_Presentation(self._struc_mgr) arrow = Prs3d_Arrow() + if veccolor is not None: + aPresentation.Color(get_color_name(veccolor)) arrow.Draw( aPresentation.GetHandle(), (pnt.as_vec() + vec).as_pnt(), @@ -207,7 +212,7 @@ def DisplayMessage(self,point,text_to_write, message_color=None, update=False): text_aspect = Prs3d.Prs3d_TextAspect() if message_color is not None: - text_aspect.SetColor(color(*message_color)) + aPresentation.Color(get_color_name(message_color)) text = Prs3d.Prs3d_Text() text.Draw(aPresentation.GetHandle(), @@ -354,6 +359,7 @@ def SetSelectionMode(self, mode=None): else: self.Context.ActivateStandardMode(mode) self.Context.UpdateSelected() + return topo_lut[topo_level] def SetSelectionModeShape(self): self.Context.CloseAllContexts() @@ -384,9 +390,12 @@ def SelectArea(self,Xmin,Ymin,Xmax,Ymax): def Select(self,X,Y): self.Context.Select() self.Context.InitSelected() + + self.selected_shapes = [] if self.Context.MoreSelected(): if self.Context.HasSelectedShape(): self.selected_shape = self.Context.SelectedShape() + self.selected_shapes.append(self.selected_shape) print "Current selection (single):",self.selected_shape else: self.selected_shape = None From 3c2d248bfcf51910a813624e934335c4e9543d07 Mon Sep 17 00:00:00 2001 From: Jelle Feringa Date: Wed, 8 Jan 2014 11:08:06 +0100 Subject: [PATCH 22/29] clean up of the example, closing issue in github --- src/examples/GEOM/partition.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/examples/GEOM/partition.py b/src/examples/GEOM/partition.py index 075b02793..47dea49fc 100644 --- a/src/examples/GEOM/partition.py +++ b/src/examples/GEOM/partition.py @@ -1,9 +1,11 @@ +from OCC.Display.SimpleGui import init_display + __author__ = 'jelle' import functools from OCC.Utils.Construct import * -from OCC import Partition +from OCC.Partition import * from OCC.TopAbs import * from OCC.TopoDS import * from OCC.Utils.Topology import Topo @@ -30,29 +32,28 @@ f1 = make_face(pl1) f2 = make_face(pl2) -disp = Display() -disp.display.DisplayShape([f1,f2]) -disp.display.FitAll() -disp.start_display() - -import ipdb; ipdb.set_trace() - -spl = Partition.Partition_Spliter() +spl = Partition_Spliter() spl.AddShape(f1) spl.AddTool(f2) -spl.Compute() +spl.Compute(TopAbs_SHAPE) shp = spl.Shape() -shp = translate_topods_from_vector(shp, gp_Vec(30,0,0)) +# start gui +display, start_display, add_menu, add_function_to_menu = init_display() -tp = Topo(shp) +# move the results a little such that we can clearly see it +shp = translate_topods_from_vector(shp, gp_Vec(30,0,0)) +# add the result to the viewer, in black +tp = Topo(shp) for i in tp.edges(): - disp(i) -disp((pl1,pl2)) + display.DisplayColoredShape(i, "BLACK") -print spl +display.DisplayShape((pl1,pl2)) +display.DisplayShape((f1,f2)) +display.FitAll() +start_display() From 33aa4bad3cea36aa803bfc1558426a82138dd307 Mon Sep 17 00:00:00 2001 From: Jelle Feringa Date: Wed, 8 Jan 2014 12:19:09 +0100 Subject: [PATCH 23/29] clean up of the PAF / GEOM examples --- src/examples/GEOM/geom.py | 117 +++--------------- src/examples/GEOM/partition.py | 7 -- src/examples/PAF/test_box_booleans_fillets.py | 13 +- 3 files changed, 21 insertions(+), 116 deletions(-) diff --git a/src/examples/GEOM/geom.py b/src/examples/GEOM/geom.py index f011dfd7d..541ef1c15 100644 --- a/src/examples/GEOM/geom.py +++ b/src/examples/GEOM/geom.py @@ -1,117 +1,28 @@ -from OCC.XCAFDoc import XCAFDoc_DocumentTool +from OCC.Display.SimpleGui import init_display +from OCC.PAF.TopologyParameterizer import geomobject_from_topods from OCC.Utils.Construct import * from OCC.PAF.Context import Parameters, ParametricModelingContext -from OCC.KBE.base import Display +#=============================================================================== +# the objective here is to make TopoDS_Shape subclasses ( think TopoDS_Vertex ) +# instances available to the parametric +# context, which requires a SGEOM.GEOM_Object, rather than a TopoDS_* instance +#=============================================================================== + +# create TopoDS_Vertex, TopoDS_Edge vertex = make_vertex( gp_Pnt() ) lineA = make_line( gp_Pnt(-1,0,0), gp_Pnt(1,0,0) ) lineB = make_line( gp_Pnt(0,-1,0), gp_Pnt(0,1,0) ) -from itertools import count - -cntr = count() - - - -#GEOM_Object::GEOM_Object(TDF_Label& theEntry, int theType) -#: _label(theEntry), _ior(""), _docID(-1) -#{ -# Handle(TDocStd_Document) aDoc = TDocStd_Owner::GetDocument(_label.Data()); -# if(!aDoc.IsNull()) { -# Handle(TDataStd_Integer) anID; -# if(aDoc->Main().FindAttribute(TDataStd_Integer::GetID(), anID)) _docID = anID->Get(); -# } -# -# theEntry.ForgetAllAttributes(Standard_True); -# -# if(!theEntry.FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), _root)) -# _root = TDataStd_TreeNode::Set(theEntry); -# -# TDataStd_Integer::Set(theEntry.FindChild(TYPE_LABEL), theType); -# -# TDataStd_UAttribute::Set(theEntry, GetObjectID()); -#} - - - - -def geomobject_from_topods(topods, pmc): - """ - returns a GEOM_Object that contains a TopoDS_Shape - :param topods: the TopoDS_Shape to add to the GEOM_Object - :param pmc: the parametric modeling context - :return: a GEOM_Object that contains :topods: - """ - # creates a GEOM_Object in the appropriate context - -# def GetObject(self, *args): -# """GetObject(self, int arg0, char theEntry) -> Handle_GEOM_Object""" -# return _SGEOM.GEOM_Engine_GetObject(self, *args) -# -# def AddObject(self, *args): -# """AddObject(self, int arg0, int arg1) -> Handle_GEOM_Object""" -# return _SGEOM.GEOM_Engine_AddObject(self, *args) - - - from OCC.SGEOM import * - - #geomobject = pmc.myEngine.AddObject(pmc.docId,cntr.next()).GetObject() - doc_tool = XCAFDoc_DocumentTool().ShapeTool(pmc.root).GetObject() - shape = TopoDS_Shape(topods) - label = doc_tool.AddShape(shape, False) - tt = GEOM_Object(label, topods.ShapeType()) - assert tt.GetEntry().IsEqual(label) == True - print 'did we fail?', tt.GetValue().IsNull(), ' should be 0' - - # the problem is that GEOM_Object.GetValue() returns the value of the - # this is the value returned by tt.GetValue(), its just an alias for: - # tt.GetLastFunction().GetObject().GetValue() # -> segfaults... - - gf = tt.GetLastFunction().GetObject() # GEOM_Function - gf.IsNull() # yep... - gf.SetValue(shape) # segfault; this is the shape that tt.GetValue() will return! - - tt.GetValue().IsNull() - - if geomobject.GetValue().IsNull(): - raise ValueError('TopoDS_Shape was not set...') - - return tt.GetHandle() +display, start_display, add_menu, add_function_to_menu = init_display() p = Parameters() pmc = ParametricModelingContext(p) pmc.register_operations(pmc.boolean_operations) +pmc.set_display(display) -v, lA, lB = map(lambda x: geomobject_from_topods(x, pmc), (vertex, lineA, lineB)) - -try: - qq = pmc.boolean_operations.MakeBoolean(lA,lB,3) - qqq = qq.GetObject().GetValue() -except Exception, e: - print e - -Display()(qqq) - -# pmc.boolean_operations.MakePartition() - -#Handle_TColStd_HSequenceOfTransient theTools, -#Handle_TColStd_HSequenceOfTransient theKeepInside, -#Handle_TColStd_HSequenceOfTransient theRemoveInside, -#Standard_Integer theLimit, -#Standard_Boolean theRemoveWebs, -#Handle_TColStd_HArray1OfInteger theMaterials, -#Standard_Integer theKeepNonlimitShapes, -#Standard_Boolean thePerformSelfIntersections) -> Handle_GEOM_Object - - -pmc.boolean_operations.MakeBoolean(v,lA, 3) - - +v, lA, lB = map(lambda x: geomobject_from_topods(pmc, x), (vertex, lineA, lineB)) +pmc.boolean_operations.MakeBoolean(lA.GetHandle(),lB.GetHandle(),3, show=True) -#TopoDS_Shape s1 = BRepPrimAPI_MakeBox(gp_Pnt(0, 0, 0), gp_Pnt(10, 30, 20)); -#TopLoc_Location location1, location2; -# -#TDF_Label lab1 = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main ())->NewShape(); -#XCAFDoc_DocumentTool::ShapeTool (aDoc->Main ())->SetShape(lab1, s1); -#TDataStd_Name::Set(lab1, "Box1"); +start_display() diff --git a/src/examples/GEOM/partition.py b/src/examples/GEOM/partition.py index 47dea49fc..7b79c82a1 100644 --- a/src/examples/GEOM/partition.py +++ b/src/examples/GEOM/partition.py @@ -1,15 +1,8 @@ from OCC.Display.SimpleGui import init_display - -__author__ = 'jelle' - -import functools - from OCC.Utils.Construct import * from OCC.Partition import * from OCC.TopAbs import * -from OCC.TopoDS import * from OCC.Utils.Topology import Topo -from OCC.KBE.base import Display liX = make_line(gp_Pnt(-10,0,0), gp_Pnt(10,0,0)) liY = make_line(gp_Pnt(0,-10,0), gp_Pnt(0,10,0)) diff --git a/src/examples/PAF/test_box_booleans_fillets.py b/src/examples/PAF/test_box_booleans_fillets.py index 692767266..468b872ba 100644 --- a/src/examples/PAF/test_box_booleans_fillets.py +++ b/src/examples/PAF/test_box_booleans_fillets.py @@ -51,16 +51,17 @@ li1 = make_line(gp_Pnt(-10,0,0), gp_Pnt(10,0,0)) li2 = make_line(gp_Pnt(0,-10,0), gp_Pnt(0,10,0)) + +# geometry that are subclassed form TopoDS_Shape ( like TopoDS_Vertex ) +# can be transformed to SGEOM.GEOM_Object +# which is required to work in a parametric context li1_geom = geomobject_from_topods(my_context, li1) li2_geom = geomobject_from_topods(my_context, li2) -yy1 = TColStd_HSequenceOfTransient() -yy2 = TColStd_HSequenceOfTransient() -yy1.Append(li1_geom.GetHandle()) -yy2.Append(li2_geom.GetHandle()) - my_context.boolean_operations.MakeBoolean(li1_geom.GetHandle(),li2_geom.GetHandle(),3, show=True) -pres1, pres2, pres_fillet = my_context.get_presentation(box1), my_context.get_presentation(box2), my_context.get_presentation(fillet_box) +pres1 = my_context.get_presentation(box1) +pres2 = my_context.get_presentation(box2) +pres_fillet = my_context.get_presentation(fillet_box) pres1.SetTransparency(.8); pres1.SetColor(12) pres2.SetTransparency(.8); pres1.SetColor(12) pres_fillet.SetColor(1) From 5e68fdc1ff9e913d634b875064f01ba9c9ac870d Mon Sep 17 00:00:00 2001 From: Jelle Feringa Date: Wed, 8 Jan 2014 12:30:11 +0100 Subject: [PATCH 24/29] clean imports --- src/examples/Display/lightened_shape.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/examples/Display/lightened_shape.py b/src/examples/Display/lightened_shape.py index 2a502bcc8..b3780ed09 100644 --- a/src/examples/Display/lightened_shape.py +++ b/src/examples/Display/lightened_shape.py @@ -22,10 +22,8 @@ from OCC.Graphic3d import * from OCC.BRepPrimAPI import * -from OCC.BRepBuilderAPI import * from OCC.V3d import * from OCC.Quantity import * -from OCC.gp import * # From 7dc84449aed2f992c674f1a55e47eed8bdc54c78 Mon Sep 17 00:00:00 2001 From: Jelle Feringa Date: Mon, 24 Mar 2014 13:42:42 +0100 Subject: [PATCH 25/29] fixes the issue of rectangles not being drawn to screen, when selecting by region, when zooming to a region --- src/addons/Display/qtDisplay.py | 40 +++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/addons/Display/qtDisplay.py b/src/addons/Display/qtDisplay.py index 777ea8d0a..f9523432c 100644 --- a/src/addons/Display/qtDisplay.py +++ b/src/addons/Display/qtDisplay.py @@ -18,7 +18,7 @@ ##along with pythonOCC. If not, see . import os,sys -from PyQt4 import QtCore, QtGui, QtOpenGL +from PyQt4 import Qt, QtCore, QtGui, QtOpenGL import OCCViewer class point(object): @@ -32,21 +32,25 @@ def set(self,obj): self.x = obj.x() self.y = obj.y() + class qtBaseViewer(QtOpenGL.QGLWidget): ''' The base Qt Widget for an OCC viewer ''' def __init__(self, parent = None): - QtOpenGL.QGLWidget.__init__(self,parent) - # self.initializeGL() - # self.initializeOverlayGL() + super(qtBaseViewer, self).__init__(parent) + self.initializeGL() + self.initializeOverlayGL() + + # both required for drawing boxes over the OpenGL image + self.setAutoFillBackground(False) + self.setAutoBufferSwap(True) + self._display = None self._inited = False self.setMouseTracking(True) #enable Mouse Tracking self.setFocusPolicy(QtCore.Qt.WheelFocus)#Strong focus # On X11, setting this attribute will disable all double buffering - self.setAttribute(QtCore.Qt.WA_PaintOnScreen) - # setting this flag implicitly disables double buffering for the widget - self.setAttribute(QtCore.Qt.WA_NoSystemBackground) + # self.setAttribute(QtCore.Qt.WA_PaintOnScreen) def GetHandle(self): return int(self.winId()) @@ -55,9 +59,6 @@ def resizeEvent(self, event): if self._inited: self._display.OnResize() - def paintEngine(self): - return None - class qtViewer3d(qtBaseViewer): def __init__(self, *kargs): qtBaseViewer.__init__(self, *kargs) @@ -118,10 +119,20 @@ def focusOutEvent(self, event): self._display.Repaint() #print 'repainted' + def resizeGL(self, width, height): + self.setupViewport(width, height) + def paintEvent(self, event): if self._inited: - self._display.Repaint() + # the jitteriness is because of the many + # and quite likely unnessecary updates of the viewer + # if you skip the update, redrawing will be much faster + # problem is that all previous rectangles will be still there too... + self._display.Context.UpdateCurrentViewer() + self.swapBuffers() + if self._drawbox: + self.makeCurrent() painter = QtGui.QPainter(self) painter.setPen(QtGui.QPen(QtGui.QColor(0,0,0), 1)) rect = QtCore.QRect(*self._drawbox) @@ -140,7 +151,8 @@ def wheelEvent(self,event): self._display.ZoomFactor(zoom_factor) def dragMoveEvent(self,event): - pass#print 'dragmove event' + #print 'dragmove event' + pass def mousePressEvent(self, event): #print 'mouse press event' @@ -176,9 +188,9 @@ def DrawBox(self, event): dy = pt.y - self.dragStartPos.y if abs( dx ) <= tolerance and abs( dy ) <= tolerance: return - self.repaint() self._drawbox = [self.dragStartPos.x, self.dragStartPos.y , dx, dy] - + self.update() + def mouseMoveEvent(self, evt): pt = point(evt.pos()) buttons = int(evt.buttons()) From 64e40f08928f33fe92ce087b03de4dba75a3172b Mon Sep 17 00:00:00 2001 From: Jelle Feringa Date: Mon, 24 Mar 2014 13:42:42 +0100 Subject: [PATCH 26/29] fixes the issue of rectangles not being drawn to screen, when selecting by region, when zooming to a region --- src/addons/Display/qtDisplay.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/addons/Display/qtDisplay.py b/src/addons/Display/qtDisplay.py index f9523432c..240b537c3 100644 --- a/src/addons/Display/qtDisplay.py +++ b/src/addons/Display/qtDisplay.py @@ -138,6 +138,7 @@ def paintEvent(self, event): rect = QtCore.QRect(*self._drawbox) painter.drawRect(rect) painter.end() + self.doneCurrent() def ZoomAll(self, evt): self._display.Zoom_FitAll() From ce20959211f7099ef8e4603fc89aa500d09be461 Mon Sep 17 00:00:00 2001 From: Jelle Feringa Date: Mon, 31 Mar 2014 18:06:39 +0200 Subject: [PATCH 27/29] When using an uppercase file extension, than that file would not load correctly --- src/addons/DataExchange/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addons/DataExchange/utils.py b/src/addons/DataExchange/utils.py index 0a76c44ee..9560f7a89 100644 --- a/src/addons/DataExchange/utils.py +++ b/src/addons/DataExchange/utils.py @@ -47,7 +47,7 @@ def shape_to_file(shape, pth, filename, format='iges'): def file_to_shape(pth): '''get a Shape from an .iges or .step file''' assert os.path.isfile(pth), '%s is not a valid file' % (pth) - ext = os.path.splitext(pth)[1] + ext = os.path.splitext(pth)[1].lower() print 'ext', ext assert ext in ['.iges', '.igs', '.stp', '.step', '.brep', '.stl'], '%s is not an readable format' % ( ext ) From 541dca7a633e31d902a2100adc25adc77099a355 Mon Sep 17 00:00:00 2001 From: Jelle Feringa Date: Mon, 28 Apr 2014 22:11:59 +0200 Subject: [PATCH 28/29] nicer trihedron, this one does not get overpainted and is more visible R,G,B -> X,Y,Z is meaningful too --- src/addons/Display/OCCViewer.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/addons/Display/OCCViewer.py b/src/addons/Display/OCCViewer.py index c43bb81b9..bca44b26f 100644 --- a/src/addons/Display/OCCViewer.py +++ b/src/addons/Display/OCCViewer.py @@ -326,7 +326,13 @@ def DisplayColoredShape(self, shapes, color='YELLOW', update=False, ): def DisplayTriedron(self): - self.View.TriedronDisplay(OCC.Aspect.Aspect_TOTP_RIGHT_LOWER, OCC.Quantity.Quantity_NOC_BLACK, 0.08, OCC.V3d.V3d_WIREFRAME) + R,G,B = OCC.Quantity.Quantity_NOC_RED,OCC.Quantity.Quantity_NOC_GREEN,OCC.Quantity.Quantity_NOC_BLUE1 + size_ratio = 0.8 + axis_diameter = 0.05 + n_facettes = 18 + scale = 0.08 + self.View.ZBufferTriedronSetup(R,G,B ,size_ratio,axis_diameter,n_facettes) + self.View.TriedronDisplay(OCC.Aspect.Aspect_TOTP_RIGHT_LOWER,OCC.Quantity.Quantity_NOC_WHITE,scale,OCC.V3d.V3d_ZBUFFER); self.Repaint() def EnableAntiAliasing(self): From b35d34c93109a8e29def2a3e2623b45c02c2f124 Mon Sep 17 00:00:00 2001 From: Jelle Feringa Date: Thu, 9 Oct 2014 23:07:01 +0200 Subject: [PATCH 29/29] WIP --- src/addons/DataExchange/STEP.py | 8 +++--- src/addons/Display/OCCViewer.py | 5 ++++ src/addons/Display/qtDisplay.py | 36 ++++++++++++++++++++---- src/addons/KBE/face.py | 10 +++++-- src/addons/Utils/Common.py | 4 +-- src/examples/OCAFBrowser/ocaf_browser.py | 4 +-- src/wrapper/Visualization/Display3d.cpp | 1 + 7 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/addons/DataExchange/STEP.py b/src/addons/DataExchange/STEP.py index 8f41cd60e..136e2a9f6 100644 --- a/src/addons/DataExchange/STEP.py +++ b/src/addons/DataExchange/STEP.py @@ -137,7 +137,7 @@ def set_tolerance(self, tolerance=0.0001): def add_shape(self, aShape): # First check the shape if aShape.IsNull(): - raise Assertion("STEPExporter Error: the shape is NULL") + raise AssertionError("STEPExporter Error: the shape is NULL") else: self._shapes.append(aShape) @@ -145,8 +145,8 @@ def write_file(self): # workaround for an OCC bug: temporarily changing the locale in order to # avoid issues when exporting, see: # http://tracker.dev.opencascade.org/view.php?id=22898 - loc = locale.getlocale() - locale.setlocale(locale.LC_ALL, 'C') + # loc = locale.getlocale() + # locale.setlocale(locale.LC_ALL, 'C') for shp in self._shapes: status = self.stepWriter.Transfer(shp, STEPControl_AsIs ) if status == IFSelect_RetDone: @@ -154,7 +154,7 @@ def write_file(self): else: return False # restoring the old locale - locale.setlocale(locale.LC_ALL, loc) + # locale.setlocale(locale.LC_ALL, loc) if self.verbose: self.stepWriter.PrintStatsTransfer() diff --git a/src/addons/Display/OCCViewer.py b/src/addons/Display/OCCViewer.py index bca44b26f..ff2dd5241 100644 --- a/src/addons/Display/OCCViewer.py +++ b/src/addons/Display/OCCViewer.py @@ -23,6 +23,7 @@ import itertools from OCC.AIS import AIS_MultipleConnectedInteractive +from OCC.MeshVS import MeshVS_Mesh, Handle_MeshVS_Mesh from OCC.TopoDS import * from OCC.Utils.Common import to_string, color from OCC.Utils.Construct import gp_Dir @@ -253,6 +254,10 @@ def DisplayShape(self, shapes, material=None, texture=None, color=None, transpar elif material: shape_to_display = OCC.AIS.AIS_Shape(shape) shape_to_display.SetMaterial(material) + if isinstance(shape, Handle_MeshVS_Mesh): + shape_to_display = shape + if isinstance(shape, MeshVS_Mesh): + shape_to_display = shape.GetHandle() else: # TODO: can we use .Set to attach all TopoDS_Shapes to this AIS_Shape instance? shape_to_display = OCC.AIS.AIS_Shape(shape) diff --git a/src/addons/Display/qtDisplay.py b/src/addons/Display/qtDisplay.py index 240b537c3..f9893e5af 100644 --- a/src/addons/Display/qtDisplay.py +++ b/src/addons/Display/qtDisplay.py @@ -21,6 +21,8 @@ from PyQt4 import Qt, QtCore, QtGui, QtOpenGL import OCCViewer +from OpenGL.GL import * + class point(object): def __init__(self,obj=None): self.x = 0 @@ -34,16 +36,34 @@ def set(self,obj): class qtBaseViewer(QtOpenGL.QGLWidget): +# class qtBaseViewer(QtGui.QWidget): ''' The base Qt Widget for an OCC viewer ''' def __init__(self, parent = None): + # super(qtBaseViewer, self).__init__(QtOpenGL.QGLFormat(QtOpenGL.QGL.SampleBuffers), parent) super(qtBaseViewer, self).__init__(parent) - self.initializeGL() - self.initializeOverlayGL() + # self.makeCurrent() + super(qtBaseViewer, self).initializeGL() + + # super(qtBaseViewer, self).initializeOverlayGL() # both required for drawing boxes over the OpenGL image + + # These are correct for the OCC viewer + # self.setAutoFillBackground(False) + # self.setAutoBufferSwap(True) + self.setAutoFillBackground(False) - self.setAutoBufferSwap(True) + # self.setAutoBufferSwap(True) + + + # ol = self.overlayContext() + # format_ = QtOpenGL.QGLFormat() + # f = format_.defaultOverlayFormat() + # f.setDoubleBuffer(True) + # ol.format().defaultFormat(format_) + # f.hasOverlay() + # f.setOverlay() self._display = None self._inited = False @@ -52,11 +72,15 @@ def __init__(self, parent = None): # On X11, setting this attribute will disable all double buffering # self.setAttribute(QtCore.Qt.WA_PaintOnScreen) + def initializeGL(self): + glEnable(GL_MULTISAMPLE) + def GetHandle(self): return int(self.winId()) def resizeEvent(self, event): if self._inited: + print "resizeEvent" self._display.OnResize() class qtViewer3d(qtBaseViewer): @@ -109,20 +133,22 @@ def Test(self): self._display.Test() def focusInEvent(self, event): - #print 'focus in!!' + print 'focus in!!' if self._inited: self._display.Repaint() def focusOutEvent(self, event): - #print 'focus out' + print 'focus out' if self._inited: self._display.Repaint() #print 'repainted' def resizeGL(self, width, height): + print "resizeGL" self.setupViewport(width, height) def paintEvent(self, event): + print "paint event qt viewer" if self._inited: # the jitteriness is because of the many # and quite likely unnessecary updates of the viewer diff --git a/src/addons/KBE/face.py b/src/addons/KBE/face.py index 697f59b42..b718ae26f 100644 --- a/src/addons/KBE/face.py +++ b/src/addons/KBE/face.py @@ -1,3 +1,4 @@ +import itertools from OCC.BRep import BRep_Tool_Surface, BRep_Tool from OCC.BRepIntCurveSurface import BRepIntCurveSurface_Inter from OCC.BRepTopAdaptor import BRepTopAdaptor_FClass2d @@ -16,7 +17,6 @@ from OCC.ShapeAnalysis import ShapeAnalysis_Surface from OCC.GeomProjLib import GeomProjLib from OCC.Adaptor3d import Adaptor3d_IsoCurve - from OCC.KBE.base import Display, KbeObject, GlobalProperties from OCC.KBE.edge import Edge from OCC.Utils.Construct import * @@ -190,12 +190,15 @@ class Face(KbeObject, TopoDS_Face): object is a Face iff part of a Solid otherwise the same methods do apply, apart from the topology obviously """ + + counter = itertools.count() + def __init__(self, face): ''' ''' - KbeObject.__init__(self, name='face') + KbeObject.__init__(self) TopoDS_Face.__init__(self, face) - + self.name = "face {0}".format(self.counter.next()) # cooperative classes self.DiffGeom = DiffGeomSurface(self) @@ -440,6 +443,7 @@ def iso_curve(self, u_or_v, param): """ uv = 0 if u_or_v == 'u' else 1 # TODO: REFACTOR, part of the Face class now... + # TODO: should use param_start & param_end to extract the iso curve given a specific domain iso = Adaptor3d_IsoCurve(self.adaptor_handle.GetHandle(), uv, param) return iso diff --git a/src/addons/Utils/Common.py b/src/addons/Utils/Common.py index 86008f6d7..476ed35b2 100644 --- a/src/addons/Utils/Common.py +++ b/src/addons/Utils/Common.py @@ -130,9 +130,9 @@ def _Tcol_dim_1(li, _type): # return pts def point_list_to_TColgp_Array1OfPnt(li): - pts = TColgp_Array1OfPnt(0, len(li)-1) + pts = TColgp_Array1OfPnt(1, len(li)+1) for n,i in enumerate(li): - pts.SetValue(n,i) + pts.SetValue(n+1,i) return pts def point2d_list_to_TColgp_Array1OfPnt2d(li): diff --git a/src/examples/OCAFBrowser/ocaf_browser.py b/src/examples/OCAFBrowser/ocaf_browser.py index 500fd1cc8..03a4fa42d 100644 --- a/src/examples/OCAFBrowser/ocaf_browser.py +++ b/src/examples/OCAFBrowser/ocaf_browser.py @@ -17,10 +17,10 @@ ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see . -from enthought.traits.ui.api import View, Item, TreeEditor, TreeNode,\ +from traitsui.api import View, Item, TreeEditor, TreeNode,\ ListEditor, VGroup -from enthought.traits.api import (HasTraits, Property, Bool, +from traits.api import (HasTraits, Property, Bool, on_trait_change, cached_property, Instance, File, Float as _Float, List, Str, Enum, Int ) diff --git a/src/wrapper/Visualization/Display3d.cpp b/src/wrapper/Visualization/Display3d.cpp index 959b61212..de9bca230 100644 --- a/src/wrapper/Visualization/Display3d.cpp +++ b/src/wrapper/Visualization/Display3d.cpp @@ -44,6 +44,7 @@ void Display3d::Init(long window_handle) #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) gd = new Graphic3d_GraphicDevice(std::getenv("DISPLAY")); printf("OSX - Graphic device created.\n"); + // no support for HiDPI / Retina devices myWindow = new Cocoa_Window (reinterpret_cast(window_handle)); printf("Cocoa window created.\n"); #else