Example #1
0
    def create(self):
        
        def hole(polycoord):
            """Polygon is a hole, if the vertices are defined clockwise."""
            
            ring = LinearRing(polycoord)
            if ring.is_ccw is False:
                return True
            else:
                return False
                
        def getHole(polycoord):
            """Create random point inside polygon."""
            
            polygon = Polygon(polycoord)
            bounds = polygon.bounds
            
            while True:
                randX = uniform(bounds[0], bounds[2])
                randY = uniform(bounds[1], bounds[3])
                randPoint = Point(randX,randY)

                if randPoint.within(polygon):
                    break
            return [randX, randY]
        
        info = ""

        # get levels and colours
        try:
            levels, levels_ok, coloursHEX_RGB, coloursRGB, coloursHEX_BGR, coloursBGR, col_ok = self.getLevels()
        except:
            QMessageBox.critical(self.widget, "Error", "Check level inputs!")
            return
        
        if not levels_ok:
            QMessageBox.critical(self.widget, "Error", "Check level ranges!")
            return
        if not col_ok:
            QMessageBox.critical(self.widget, "Error", "Check colours!")
            return
        
        # read input meshes
        try:
            x, y, z, triangles = fh.readT3STriangulation(self.ui.lineEditInput.text())
            triang = tri.Triangulation(x, y, triangles)
        except:
            QMessageBox.critical(self.widget, "Error", "Not able to load mesh file!\nCheck filename or content!")
            return

        contours = []
        
        # loop over contour levels
        for level in range(len(levels)-1):

            # create contour plot with matplotlib.pyplot.tricontourf
            cs = plt.tricontourf(triang, z, levels=[levels[level], levels[level+1]], colors=coloursHEX_RGB[level])

            # instantiate the dictionary for the triangulation
            geometry = {}
            geometry["vertices"] = []
            geometry["segments"] = []
            geometry["holes"] = []

            # nodecounter for level
            nodeID = 0
            
            # loop over matplotlib collection
            for cc in cs.collections:
                for pp in cc.get_paths():
                    
                    # paths to polygons
                    polys = pp.to_polygons()

                    eps = 0.000001
                    polys_ = []
                    
                    # loop over polygons
                    for pID in range(len(polys)):
                        poly = polys[pID]
                        nodeIDs = []
                        
                        if len(poly) > 1:
                            
                            # add random point if polygon defines a hole
                            if hole(poly):
                                geometry["holes"].append(getHole(poly))
                            
                            # nodecounter for polygon
                            counter = 0
                            
                            # add vertices and segments
                            # triangle crashes, if vertices are too close to each other,
                            # which would result in zero area triangles
                            for vID in range(len(poly)):
                                vert = np.array(poly[vID])
                                vert = vert.reshape((1,2))
                                
                                # first vertice in polygon
                                if len(geometry["vertices"]) == 0:
                                    geometry["vertices"] = np.array(vert)
                                    nodeIDs.append(nodeID)
                                    counter += 1
                                    nodeID += 1
                                else:
                                    # subtract actual vertice from array of vertices
                                    vertices_ = geometry["vertices"] - vert
                                    
                                    # calculate the length of the vectors
                                    norm = np.linalg.norm(vertices_, axis = 1)
                                    
                                    # get smallest vector norm
                                    min_norm = norm.min()

                                    # if smallest vector norm is greater than a defined value, apply vertice
                                    if min_norm > eps:
                                        counter += 1
                                        geometry["vertices"] = np.concatenate((geometry["vertices"], vert))
                                        nodeIDs.append(nodeID)
                                        nodeID += 1
                                    # else get index of smallest vector norm and apply node-ID
                                    else:
                                        min_index = np.argmin(norm)
                                        # print "comparison: ", min_index, geometry["vertices"][min_index], vID, poly[vID]
                                        nodeIDs.append(min_index)

                            # close polygon by adding id from first vertice
                            nodeIDs.append(nodeID-counter)

                        polys_.append(nodeIDs)

                    # create segments
                    for pID in range(len(polys_)):
                        for nID in range(len(polys_[pID])-1):
                            geometry["segments"].append([polys_[pID][nID], polys_[pID][nID+1]])

            # delete holes from dictionary, if no holes exist
            if len(geometry["holes"]) == 0:
                del geometry["holes"]
            if len(geometry["vertices"]) >= 3:
                t = triangle.triangulate(geometry, 'p')
                contours.append(t)
            else:
                contours.append(None)
                
# plot triangulation using matplotlib
#            plt.figure(1)
#            ax1 = plt.subplot(111, aspect='equal')
#            triangle.plot.plot(ax1, **t)
#            plt.show()

        xLeg = max(x)
        yLeg = min(y)
        origin = (xLeg, yLeg)
        
        title = self.ui.lineEditOutputLegendTitle.text()
        subtitle = self.ui.lineEditOutputLegendSubtitle.text()

        if self.ui.checkBoxOutputSolid.isChecked():
            try:
                fh.writeContSolidDXF(
                    self.ui.lineEditOutputSolid.text(), 
                    contours,
                    levels,
                    coloursRGB, 
                    self.ui.lineEditOutputLayer.text(),
                    self.ui.checkBoxOutputLegend.isChecked(),
                    title,
                    subtitle,
                    origin,
                    self.ui.lineEditOutputLegendSeparator.text(),
                    self.ui.checkBoxOutputLegendReverse.isChecked()
                )
                info += "Contours:\n"
                info += " - Contours created with {0} levels.\n".format(len(levels)) 
                if self.ui.checkBoxOutputLegend.isChecked():
                    info += " - Legend created.\n"
                info += " - DXF written to {0}.\n\n".format(self.ui.lineEditOutputSolid.text())
            except:
                info += " - ERROR: Not able to write contour to dxf!\n"
            
        if self.ui.checkBoxOutputLine.isChecked():
            try:
                fh.writeContIsoLineDXF(
                self.ui.lineEditOutputLine.text(), 
                contours, 
                levels,
                coloursRGB, 
                self.ui.lineEditOutputLayer.text(),
                self.ui.checkBoxOutputLegend.isChecked(),
                title,
                subtitle,
                origin,
                self.ui.lineEditOutputLegendSeparator.text(),
                self.ui.checkBoxOutputLegendReverse.isChecked()
                )
                info += "Isolines:\n"
                info += " - Isolines created with {0} levels.\n".format(len(levels))
                if self.ui.checkBoxOutputLegend.isChecked():
                    info += " - Legend created.\n"
                info += " - DXF written to {0}.\n".format(self.ui.lineEditOutputLine.text())
            except:
                info += " - ERROR: Not able to write isolines to dxf!\n"            

        QMessageBox.information(self.widget, "Module Cont2DXF", info)
Example #2
0
    def create(self):
        
        info = ""
        info += "Input data:\n"
        
        textfile = []
        
        # read input meshes
        try:
            x, y, z, triangles = fh.readT3STriangulation(self.ui.lineEditInputMesh.text())
            info += " - Mesh loaded with {0} nodes and {1} elements.\n".format(len(x), len(triangles))
        except:
            QMessageBox.critical(self, "Error", "Not able to load mesh file!\nCheck filename or content!")
            return        

        try:
            tube_coords, tubes = fh.readI2S(self.ui.lineEditInputLineSet.text())
            info += " - Line Set loaded with {0} lines.\n".format(len(tubes))
        except:
            QMessageBox.critical(self.widget, "Error", "Not able to load *.i2s file!\nCheck filename or content!")
            return

        # reshape coordinates
        a = np.array([x, y])
        b = np.reshape(a, (2*len(x)), order='F')
        mesh_coords = np.reshape(b, (len(x), 2))
        
        Rel = str(self.ui.doubleSpinBoxRel.value())
        Ce1 = str(self.ui.doubleSpinBoxCe1.value())
        Ce2 = str(self.ui.doubleSpinBoxCe2.value())
        Cs1 = str(self.ui.doubleSpinBoxCs1.value())
        Cs2 = str(self.ui.doubleSpinBoxCs2.value())
        Lrg = str(self.ui.doubleSpinBoxLrg.value())
        Hau = str(self.ui.doubleSpinBoxHau.value())
        Clp = str(self.ui.spinBoxClp.value())
        L12 = str(self.ui.doubleSpinBoxL12.value())
        
        textfile.append("Relaxation")
        textfile.append(Rel)
        textfile.append("I1\tI2\tCe1\tCe2\tCs1\tCs2\tLrg\tHau\tClp\tL12\tz1\tz2")
        
        for tID in tubes:
            line = ""
            tube = tubes[tID]
            
            nodes = ""
            z_val = ""
            
            for i in range(2):
                p = tube_coords[tube[i]]
                vert = np.array(p)
                vert = vert.reshape((1,2))
                temp = mesh_coords-p
                norm = np.linalg.norm(temp, axis = 1)
                I = np.argmin(norm)+1
                nodes += str(I)
                nodes += "\t"
                z_val += str(z[I-1])
                z_val += "\t"

            line += nodes
            line += str(Ce1) + "\t"
            line += str(Ce2) + "\t"
            line += str(Cs1) + "\t"
            line += str(Cs2) + "\t"
            line += str(Lrg) + "\t"
            line += str(Hau) + "\t"
            line += str(Clp) + "\t"
            line += str(L12) + "\t"
            line += z_val

            textfile.append(line)

        info += "\nOutput data:\n"
                    
        try:
            fh.writeTextFile(self.ui.lineEditOutput.text(), textfile)
            info += " - Tubes data file written to {0}.\n".format(self.ui.lineEditOutput.text())
        except:
            QMessageBox.critical(self.widget, "Error", "Not able to write tubes data file!")
            return
    
        QMessageBox.information(self.widget, "Module Tube", info)  
Example #3
0
    def create(self):
        
        info = ""
        
        dx = self.ui.doubleSpinBoxDX.value()
        dy = self.ui.doubleSpinBoxDY.value()
        
        SMin = self.ui.doubleSpinBoxSMin.value()
        SMax = self.ui.doubleSpinBoxSMax.value()
        
        scale = self.ui.doubleSpinBoxSizeFactor.value()
        
        eps = self.ui.doubleSpinBoxLessThan.value()
        
        # read input meshes
        
        try:
            x, y, zMajor, triangles = fh.readT3STriangulation(self.ui.lineEditInputT3SMajor.text())
        except:
            QMessageBox.critical(self, "Error", "Not able to load mesh file!\nCheck filename or content!")
            return
        
        minor = False
        if self.ui.lineEditInputT3SMinor.text() != "":
            minor = True
            try:
                x, y, zMinor, triangles = fh.readT3STriangulation(self.ui.lineEditInputT3SMinor.text())
            except:
                QMessageBox.critical(self.widget, "Error", "Not able to load mesh file!\nCheck filename or content!")
                return            
            
        scalarNodes = {}
        sCounter = 0

        xMin = min(x)
        xMax = max(x)
        yMin = min(y)
        yMax = max(y)

        triang = tri.Triangulation(x, y, triangles)
        
        # Interpolate to regularly-spaced quad grid.

        # origin of scalar
        x0 = floor(xMin/dx)*dx
        y0 = floor(yMin/dy)*dy

        # number of nodes in x- and y-direction
        nx = int(ceil(xMax/dx) - floor(xMin/dx))
        ny = int(ceil(yMax/dy) - floor(yMin/dy))

        xGrid, yGrid = np.meshgrid(np.linspace(x0, x0+nx*dx, nx+1), np.linspace(y0, y0+ny*dy, ny+1))
        info += " - Grid created with {0} x {1} points:\n\t- dx = {2}\n\t- dy = {3}\n\t- x(min) = {4}\n\t- y(min) = {5}\n\t- x(max) = {6}\n\t- y(max) = {7}\n".format(nx, ny, dx, dy, x0, y0, x0+nx*dx, y0+ny*dy)

        interpLinMajor = tri.LinearTriInterpolator(triang, zMajor)
        zGridMaj = interpLinMajor(xGrid, yGrid)

        zGridMin = []
        if minor is True:
            interpLinMinor = tri.LinearTriInterpolator(triang, zMinor)
            zGridMin = interpLinMinor(xGrid, yGrid)
            
        for iy in range(len(xGrid)):
            for ix in range(len(xGrid[0])):
                if minor is True:
                    scalarNodes[sCounter] = [xGrid[iy][ix], yGrid[iy][ix], zGridMaj[iy][ix], zGridMin[iy][ix]]
                    sCounter += 1
                else:
                    scalarNodes[sCounter] = [xGrid[iy][ix], yGrid[iy][ix], zGridMaj[iy][ix], None]
                    sCounter += 1                    

        useMono = self.ui.checkBoxMonochrome.isChecked()
        fname = self.ui.lineEditOutput.text()
        info += "\n - Number of interpolated values: {0}".format(len(scalarNodes))

        try:
            nOfValues = fh.writeScalarDXF(scalarNodes, SMin, SMax, eps, scale, self.scalarSymbol, useMono, fname)
            info += "\n - {0} values written to {1}".format(nOfValues, fname)
        except:
            QMessageBox.critical(self.widget, "Error", "Not able to write DXF file!")
            return

        QMessageBox.information(self.widget, "Module ScalarDXF", info)