def __init__(self, parent, profile=None): QGLViewer.__init__(self, parent) self.__profile = None self.__position = 0 self.__positionCurve = None self.increment = 0.01 self._axisScaleTolerance = abs(pi / 8.) # (radians) #states self.__oldY = None self.__scalingDirection = None #ranges self.__param_min = 0.0 self.__param_max = 1.0 # --rendering components -- self.factor = [1., 1., 1.] #x, y, z scene scaling factors. self.discretizer = Discretizer() self.renderer = GLRenderer(self.discretizer) self.renderer.renderingMode = GLRenderer.Dynamic # -- addons -- self._addons = [] self.visualSections = VisualCrossSectionsAddOn(self) self.grids = GridAddOn(self) self.userSlices = UserSlicesAddOn(self)
def sc_to_blender (sc) : """Export each shape in the scene as a new object :Parameters: - `sc` (Scene) - the scene to transform :Returns Type: None """ bldsc = Scene.GetCurrent() #fill with shapes t = time.time() d = Discretizer() for ind,shp in enumerate(sc) : if ind % 10 == 0 : print(ind) sys.stdout.flush() ob = shp_to_blender(shp,d) bldsc.link(ob) ob.sel = True print() print('Time :', time.time() - t) #return print("created") bldsc.update(1) Blender.Redraw() return ob
def __init__(self,parent, profile=None): QGLViewer.__init__(self,parent) self.__profile = None self.__position = 0 self.__positionCurve = None self.increment = 0.01 self._axisScaleTolerance = abs(pi/8.) # (radians) #states self.__oldY = None self.__scalingDirection = None #ranges self.__param_min = 0.0 self.__param_max = 1.0 # --rendering components -- self.factor = [1., 1., 1.] #x, y, z scene scaling factors. self.discretizer = Discretizer() self.renderer = GLRenderer(self.discretizer) self.renderer.renderingMode = GLRenderer.Dynamic # -- addons -- self._addons = [] self.visualSections = VisualCrossSectionsAddOn(self) self.grids = GridAddOn(self) self.userSlices = UserSlicesAddOn(self)
class ProfileViewer(QGLViewer): _posCurveColorF = [0.0, 1.0, 0.0] positionChanged = QtCore.Signal(int) userSectionHighlighted = QtCore.Signal(object, object) def __init__(self, parent, profile=None): QGLViewer.__init__(self, parent) self.__profile = None self.__position = 0 self.__positionCurve = None self.increment = 0.01 self._axisScaleTolerance = abs(pi / 8.) # (radians) #states self.__oldY = None self.__scalingDirection = None #ranges self.__param_min = 0.0 self.__param_max = 1.0 # --rendering components -- self.factor = [1., 1., 1.] #x, y, z scene scaling factors. self.discretizer = Discretizer() self.renderer = GLRenderer(self.discretizer) self.renderer.renderingMode = GLRenderer.Dynamic # -- addons -- self._addons = [] self.visualSections = VisualCrossSectionsAddOn(self) self.grids = GridAddOn(self) self.userSlices = UserSlicesAddOn(self) def init(self): self.camera().setUpVector(Vec(0, 1, 0)) self.camera().setType(Camera.ORTHOGRAPHIC) self.camConstraint = WorldConstraint() self.camera().frame().setConstraint(self.camConstraint) self.camera().setZClippingCoefficient(4) #arbitrary. self.showEntireScene() def set_axis_scale_tolerance(self, tolerance): self._axisScaleTolerance = abs(tolerance) def set_profile(self, profile): if profile is not None: profile.add_update_callback(self.__profileChanged) self.__profile = profile # -- recompute stuff -- self.__param_min, self.__param_max = profile.get_param_range() self.increment = (self.__param_max - self.__param_min) / 100 for addon in self._addons: addon._init_from_profile(profile) self.set_position(self.range()[0]) else: self.__clearCaches() self.__profile = None def profile(self): return self.__profile def range(self): return self.__param_min, self.__param_max def position(self): return self.__position def set_position(self, position): # -- clamp position -- min, max = self.range() if position > max: position = max if position < min: position = min self.__position = position self.update_displayed_geometry() self.positionChanged.emit(position) if position not in self.__profile: position = self.round_within_increment(position) if position in self.__profile: self.userSectionHighlighted.emit(position, self.__profile[position]) def round_within_increment(self, pos): keys = list( map(self.unnormalised_parameter, iter(self.__profile.keys()))) for k in keys: if abs(k - pos) <= self.increment: return k return pos ######################### # Normalisation Helpers # ######################### def normalised_parameter(self, par, **kwargs): if self.__profile: return self.__profile.normalised_parameter(par, **kwargs) def normalised_abscissa(self, par, **kwargs): if self.__profile: return self.__profile.normalised_abscissa(par, **kwargs) def unnormalised_parameter(self, par, **kwargs): if self.__profile: return self.__profile.unnormalised_parameter(par, **kwargs) def unnormalised_abscissa(self, par, **kwargs): if self.__profile: return self.__profile.unnormalised_abscissa(par, **kwargs) ################# # Painting code # ################# def draw(self): self.setBackgroundColor(QtGui.QColor(0, 0, 0)) glDisable(GL_LIGHTING) glEnable(GL_LINE_SMOOTH) glEnable(GL_BLEND) glEnable(GL_ALPHA_TEST) glAlphaFunc(GL_GREATER, 0.1) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glMatrixMode(GL_MODELVIEW) glPushMatrix() mat = 16 * [0] mat[0] = self.factor[0] mat[5] = self.factor[1] mat[10] = self.factor[2] mat[15] = 1. glMultMatrixd(mat) if self.__profile is not None: self.discretizer.clear() if self.__positionCurve: for addon in self._addons: addon._draw(self.renderer) glColor4f(0.0, 1.0, 0.0, 1.0) glDisable(GL_DEPTH_TEST) self.__positionCurve.apply(self.renderer) glEnable(GL_DEPTH_TEST) glPopMatrix() ############################### # Qt Event Handlers overloads # ############################### def mousePressEvent(self, event): if event.button() == QtCore.Qt.MidButton: self.__oldX = event.x() self.__oldY = event.y() else: QGLViewer.mousePressEvent(self, event) def mouseReleaseEvent(self, event): self.__oldX = None self.__oldY = None self.__scalingDirection = None QGLViewer.mouseReleaseEvent(self, event) def mouseMoveEvent(self, event): if self.__oldY is not None: pos = self.__position #some values that are used a bit everywhere newX, newY = event.x(), event.y() xDiff = float(newX - self.__oldX) yDiff = float(newY - self.__oldY) cartDist = sqrt(yDiff**2 + xDiff**2) mod = event.modifiers() if mod != QtCore.Qt.ControlModifier: delta = newY - self.__oldY if delta > 0: pos += self.increment elif delta < 0: pos -= self.increment self.__oldY = newY self.set_position(pos) elif self.__scalingDirection is None: if cartDist < 50: #pixels return #compute direction coefficient of the mouse pointer to the screen center if xDiff == 0.0: return pA = atan2(yDiff, xDiff) tol = self._axisScaleTolerance #compute projected direction coefficients of axes camera = self.camera() origin = camera.getProjectedCoordinatesOf(Vec(0., 0., 0.)) xProj = camera.getProjectedCoordinatesOf(Vec(1., 0., 0.)) yProj = camera.getProjectedCoordinatesOf(Vec(0., 1., 0.)) zProj = camera.getProjectedCoordinatesOf(Vec(0., 0., 1.)) xVec = (xProj[0] - origin[0]), (xProj[1] - origin[1]) yVec = (yProj[0] - origin[0]), (yProj[1] - origin[1]) zVec = (zProj[0] - origin[0]), (zProj[1] - origin[1]) #angles if xVec[0] == 0.0 or yVec[0] == 0.0 or zVec[0] == 0.0: return xA = atan(xVec[1] / xVec[0]) yA = atan(yVec[1] / yVec[0]) zA = atan(zVec[1] / zVec[0]) dire = min((abs(xA % pi - pA % pi), 0, pA, xVec), (abs(yA % pi - pA % pi), 1, pA, yVec), (abs(zA % pi - pA % pi), 2, pA, zVec)) self.__scalingDirection = dire if (dire[0] <= tol) else None elif self.__scalingDirection is not None: angD, dire, angle, vec = self.__scalingDirection #cartDist is used to obtain a significant difference #or else computations are screwed. if xDiff != 0.0 and yDiff != 0 and cartDist > 5: pA = atan2(yDiff, xDiff) if pA < 0: pA += 2 * pi if angle < 0: angle += 2 * pi angleDiv = int(angle / pi * 2) mouseDiv = int(pA / pi * 2) positive = angleDiv == mouseDiv f = self.factor[dire] f = f * 1.02 if positive else f * 0.98 self.factor[dire] = f self.__oldY = newY self.__oldX = newX self.update() else: QGLViewer.mouseMoveEvent(self, event) def keyPressEvent(self, event): key = event.key() if key in [QtCore.Qt.Key_Return, QtCore.Qt.Key_Return]: self.__profile.create_cross_section(self.__position) elif key == QtCore.Qt.Key_Delete: position = self.round_within_increment(self.__position) if position in self.__profile: del self.__profile[position] ############################## # Internal State Maintenance # ############################## def update_displayed_geometry(self): if self.__profile: # -- 'add-ons' -- for addon in self._addons: addon._compute(self.__profile) self.__positionCurve = self.__profile(self.__position) self.update() def __clearCaches(self): for addon in self._addons: addon.clear_caches() def __profileChanged(self): # -- cleanup caches -- self.__clearCaches() # -- recompute stuff -- self.__param_min, self.__param_max = self.__profile.get_param_range() self.increment = (self.__param_max - self.__param_min) / 100 for addon in self._addons: addon._interpolation_changed() self.update_displayed_geometry()
def geometry_to_blender (geom, bld_mesh = None, discretizer = None) : """Create a blender mesh Paint the faces too if needed :Parameters: - `geom` (pgl.Geometry) - the geometry to transform - `bld_mesh` (Mesh) - a mesh in which to append the shape. If None, a blank new one will be created - `discretizer` (Discretizer) - algorithm to triangulate the geometry :Returns Type: Mesh """ #create bld_mesh if bld_mesh is None : if geom.isNamed() : name = geom.name else : name = "pglgeom%d" % geom.getId() bld_mesh = Mesh.New(name) #geometry (mesh) if discretizer is None: d = Discretizer() else: d = discretizer geom.apply(d) geom = d.result #fill mesh pts = array(geom.pointList) nbv = len(bld_mesh.verts) faces = nbv + array(geom.indexList) bld_mesh.verts.extend(pts) nbf = len(bld_mesh.faces) bld_mesh.faces.extend(faces.tolist() ) #set vertex colors if needed mat = None if not geom.isColorListToDefault() : bld_mesh.vertexColors = True #create material to render mesh colors try : mat = Material.Get("default_vtx_mat") except NameError : mat = Material.New("default_vtx_mat") mat.mode += Material.Modes['VCOL_PAINT'] bld_mesh.materials = [mat] #modify color list to duplicate colors per face per vertex if geom.colorPerVertex and geom.isColorIndexListToDefault() : #each vertex has a color for i,inds in enumerate(faces) : face = bld_mesh.faces[nbf + i] for j,v in enumerate(face) : col = face.col[j] pglcol = geom.colorList[geom.indexList[i][j] ] col.r = pglcol.red col.g = pglcol.green col.b = pglcol.blue col.a = pglcol.alpha elif geom.colorPerVertex and not geom.isColorIndexListToDefault() : #each local vertex of each face has a color for i,inds in enumerate(geom.colorIndexList) : face = bld_mesh.faces[nbf + i] for j,v in enumerate(face) : col = face.col[j] pglcol = geom.colorList[inds[j] ] col.r = pglcol.red col.g = pglcol.green col.b = pglcol.blue col.a = pglcol.alpha else : #each face has a color for i,col in enumerate(geom.colorList) : face = bld_mesh.faces[nbf + i] R,G,B,A = col.red,col.green,col.blue,col.alpha for j,v in enumerate(face) : col = face.col[j] col.r = R col.g = G col.b = B col.a = A # #assign # for fid in xrange(nb,len(bld_mesh.faces) ) : # face = bld_mesh.faces[fid] # for i,v in enumerate(face) : # col = face.col[i] # col.r = ambient.red # col.g = ambient.green # col.b = ambient.blue # for vtx in bld_mesh.verts : # vtx.sel = 0 #return return bld_mesh,mat
class ProfileViewer (QGLViewer): _posCurveColorF = [0.0,1.0,0.0] positionChanged = QtCore.Signal(int) userSectionHighlighted = QtCore.Signal(object, object) def __init__(self,parent, profile=None): QGLViewer.__init__(self,parent) self.__profile = None self.__position = 0 self.__positionCurve = None self.increment = 0.01 self._axisScaleTolerance = abs(pi/8.) # (radians) #states self.__oldY = None self.__scalingDirection = None #ranges self.__param_min = 0.0 self.__param_max = 1.0 # --rendering components -- self.factor = [1., 1., 1.] #x, y, z scene scaling factors. self.discretizer = Discretizer() self.renderer = GLRenderer(self.discretizer) self.renderer.renderingMode = GLRenderer.Dynamic # -- addons -- self._addons = [] self.visualSections = VisualCrossSectionsAddOn(self) self.grids = GridAddOn(self) self.userSlices = UserSlicesAddOn(self) def init(self): self.camera().setUpVector(Vec(0,1,0)) self.camera().setType(Camera.ORTHOGRAPHIC) self.camConstraint = WorldConstraint() self.camera().frame().setConstraint(self.camConstraint) self.camera().setZClippingCoefficient(4) #arbitrary. self.showEntireScene() def set_axis_scale_tolerance(self, tolerance): self._axisScaleTolerance = abs(tolerance) def set_profile(self, profile): if profile is not None: profile.add_update_callback(self.__profileChanged) self.__profile = profile # -- recompute stuff -- self.__param_min,self.__param_max=profile.get_param_range() self.increment = (self.__param_max - self.__param_min)/100 for addon in self._addons: addon._init_from_profile(profile) self.set_position(self.range()[0]) else: self.__clearCaches() self.__profile = None def profile(self): return self.__profile def range(self): return self.__param_min, self.__param_max def position(self): return self.__position def set_position(self, position): # -- clamp position -- min, max = self.range() if position > max: position = max if position < min: position = min self.__position=position self.update_displayed_geometry() self.positionChanged.emit(position) if position not in self.__profile: position = self.round_within_increment(position) if position in self.__profile: self.userSectionHighlighted.emit(position, self.__profile[position]) def round_within_increment(self, pos): keys = map(self.unnormalised_parameter, self.__profile.iterkeys()) for k in keys: if abs(k-pos) <= self.increment: return k return pos ######################### # Normalisation Helpers # ######################### def normalised_parameter(self, par, **kwargs): if self.__profile: return self.__profile.normalised_parameter(par, **kwargs) def normalised_abscissa(self, par, **kwargs): if self.__profile: return self.__profile.normalised_abscissa(par, **kwargs) def unnormalised_parameter(self, par, **kwargs): if self.__profile: return self.__profile.unnormalised_parameter(par, **kwargs) def unnormalised_abscissa(self, par, **kwargs): if self.__profile: return self.__profile.unnormalised_abscissa(par, **kwargs) ################# # Painting code # ################# def draw(self): self.setBackgroundColor(QtGui.QColor(0,0,0)) glDisable(GL_LIGHTING) glEnable(GL_LINE_SMOOTH) glEnable(GL_BLEND) glEnable(GL_ALPHA_TEST) glAlphaFunc ( GL_GREATER, 0.1 ) glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glMatrixMode(GL_MODELVIEW) glPushMatrix() mat = 16*[0] mat[0] = self.factor[0] mat[5] = self.factor[1] mat[10] = self.factor[2] mat[15] = 1. glMultMatrixd(mat) if self.__profile is not None: self.discretizer.clear() if self.__positionCurve: for addon in self._addons: addon._draw(self.renderer) glColor4f(0.0,1.0,0.0,1.0) glDisable(GL_DEPTH_TEST) self.__positionCurve.apply(self.renderer) glEnable(GL_DEPTH_TEST) glPopMatrix() ############################### # Qt Event Handlers overloads # ############################### def mousePressEvent(self, event): if event.button() == QtCore.Qt.MidButton: self.__oldX = event.x() self.__oldY = event.y() else: QGLViewer.mousePressEvent(self, event) def mouseReleaseEvent(self, event): self.__oldX = None self.__oldY = None self.__scalingDirection = None QGLViewer.mouseReleaseEvent(self, event) def mouseMoveEvent(self, event): if self.__oldY is not None: pos = self.__position #some values that are used a bit everywhere newX, newY = event.x(), event.y() xDiff = float(newX-self.__oldX) yDiff = float(newY-self.__oldY) cartDist = sqrt(yDiff**2+xDiff**2) mod = event.modifiers() if mod != QtCore.Qt.ControlModifier: delta = newY - self.__oldY if delta > 0: pos += self.increment elif delta < 0: pos -= self.increment self.__oldY = newY self.set_position(pos) elif self.__scalingDirection is None: if cartDist < 50 : #pixels return #compute direction coefficient of the mouse pointer to the screen center if xDiff==0.0: return pA = atan2(yDiff,xDiff) tol = self._axisScaleTolerance #compute projected direction coefficients of axes camera = self.camera() origin = camera.getProjectedCoordinatesOf(Vec(0.,0.,0.)) xProj = camera.getProjectedCoordinatesOf(Vec(1.,0.,0.)) yProj = camera.getProjectedCoordinatesOf(Vec(0.,1.,0.)) zProj = camera.getProjectedCoordinatesOf(Vec(0.,0.,1.)) xVec = (xProj[0] - origin[0]),(xProj[1] - origin[1]) yVec = (yProj[0] - origin[0]),(yProj[1] - origin[1]) zVec = (zProj[0] - origin[0]),(zProj[1] - origin[1]) #angles if xVec[0]==0.0 or yVec[0]==0.0 or zVec[0]==0.0: return xA = atan(xVec[1]/xVec[0]) yA = atan(yVec[1]/yVec[0]) zA = atan(zVec[1]/zVec[0]) dire = min( ( abs(xA%pi-pA%pi),0,pA,xVec), ( abs(yA%pi-pA%pi),1,pA,yVec), ( abs(zA%pi-pA%pi),2,pA,zVec) ) self.__scalingDirection = dire if (dire[0] <= tol) else None elif self.__scalingDirection is not None: angD, dire, angle, vec = self.__scalingDirection #cartDist is used to obtain a significant difference #or else computations are screwed. if xDiff != 0.0 and yDiff != 0 and cartDist > 5 : pA = atan2(yDiff,xDiff) if pA < 0: pA += 2*pi if angle < 0: angle +=2*pi angleDiv = int(angle/pi*2) mouseDiv = int(pA/pi*2) positive = angleDiv == mouseDiv f = self.factor[dire] f = f*1.02 if positive else f*0.98 self.factor[dire] = f self.__oldY = newY self.__oldX = newX self.update() else: QGLViewer.mouseMoveEvent(self, event) def keyPressEvent(self, event): key = event.key() if key in [QtCore.Qt.Key_Return,QtCore.Qt.Key_Return]: self.__profile.create_cross_section(self.__position) elif key == QtCore.Qt.Key_Delete: position = self.round_within_increment(self.__position) if position in self.__profile: del self.__profile[position] ############################## # Internal State Maintenance # ############################## def update_displayed_geometry(self): if self.__profile: # -- 'add-ons' -- for addon in self._addons: addon._compute(self.__profile) self.__positionCurve = self.__profile(self.__position) self.update() def __clearCaches(self): for addon in self._addons: addon.clear_caches() def __profileChanged(self): # -- cleanup caches -- self.__clearCaches() # -- recompute stuff -- self.__param_min,self.__param_max=self.__profile.get_param_range() self.increment = (self.__param_max - self.__param_min)/100 for addon in self._addons: addon._interpolation_changed() self.update_displayed_geometry()