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)
Beispiel #2
0
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()
Beispiel #5
0
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()