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)
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)
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)