def GetDrawMatrix(self, get_the_appropriate_orthogonal): if get_the_appropriate_orthogonal: # choose from the three orthoganal possibilities, the one where it's z-axis closest to the camera direction vx, vy = self.current_viewport.view_point.GetTwoAxes(False, 0) o = geom.Point3D(0, 0, 0) if self.current_coordinate_system: o.Transform(self.current_coordinate_system.GetMatrix()) return geom.Matrix(o, vx, vy) mat = geom.Matrix() if self.current_coordinate_system: mat = self.current_coordinate_system.GetMatrix() return mat
def Mirror(): if cad.GetNumSelected() == 0: wx.GetApp().PickObjects('Pick objects to mirror') if cad.GetNumSelected() == 0: return config = HeeksConfig() selected_items = cad.GetSelectedObjects() cad.ClearSelection(False) copy = config.ReadBool("MirrorCopy", False) axis = geom.Point3D(0, 0, 1) pos = geom.Point3D(0, 0, 0) axis.x = config.ReadFloat("MirrorAxisX", 1.0) axis.y = config.ReadFloat("MirrorAxisY", 0.0) axis.z = config.ReadFloat("MirrorAxisZ", 0.0) pos.x = config.ReadFloat("MirrorPosX", 0.0) pos.y = config.ReadFloat("MirrorPosY", 0.0) pos.z = config.ReadFloat("MirrorPosZ", 0.0) result, axis, pos, copy = InputMirrorPlane(axis, pos, copy, 'Mirror') if not result: return config.WriteBool("MirrorCopy", copy) config.WriteFloat("MirrorAxisX", axis.x) config.WriteFloat("MirrorAxisY", axis.y) config.WriteFloat("MirrorAxisZ", axis.z) config.WriteFloat("MirrorPosX", pos.x) config.WriteFloat("MirrorPosY", pos.y) config.WriteFloat("MirrorPosZ", pos.z) cad.StartHistory() mat = geom.Matrix() x, y = axis.ArbitraryAxes() axis_mat = geom.Matrix(pos, x, y) inv_mat = axis_mat.Inverse() mat.Multiply(inv_mat) # transform so axis goes to z axis mat.Scale3(1.0, 1.0, -1.0) # mirror in z axis mat.Multiply(axis_mat) # transform back to where it was for object in selected_items: if copy: if object.CanBeCopied(): object = object.MakeACopy() object.Transform(mat) cad.AddUndoably(object) else: cad.TransformUndoably(object, mat) cad.EndHistory()
def GetMatrices(self, matrices): m2 = geom.Matrix() shift_m2 = geom.Matrix() shift_m2.Translate(geom.Point3D(self.x_shift2, self.y_shift2, 0.0)) shift_m1 = geom.Matrix() shift_m1.Translate(geom.Point3D(self.x_shift1, self.y_shift1, 0.0)) for j in range(0, self.copies2): m = geom.Matrix(m2) for i in range(0, self.copies1): matrices.append(m) m = m * shift_m1 m2 = m2 * shift_m2
def ExportFiles(self, path): wing = self.MakeStlSolid() wing.WriteStl(path) outline = wing.Shadow(geom.Matrix(), True) outline.Offset(self.pattern_border) pattern = self.MakePatternedArea(outline, wing.GetBox()) pattern_stl = self.MakeExtrudedAreaSolid(pattern, wing.GetBox().MinZ() - 10, wing.GetBox().MaxZ() + 10) pattern_path = path[:-4] + ' pattern.stl' pattern_stl.WriteStl(pattern_path) outer_box = wing.GetBox() outer_box.InsertPoint(outer_box.MinX() - 1.0, outer_box.MinY() - 1.0, outer_box.MinZ() - 1.0) outer_box.InsertPoint(outer_box.MaxX() + 1.0, outer_box.MaxY() + 1.0, outer_box.MaxZ() + 1.0) for i in range(0, self.split_into_pieces): stl = self.MakeCuboidSection(i, self.split_into_pieces, wing.GetBox(), 1.0) indexstr = str(i) if len(indexstr) < 2: indexstr = '0' + indexstr stl.WriteStl(path[:-4] + ' section' + indexstr + '.stl')
def __init__(self, mod=1.0, num_teeth=12): Object.__init__(self, 0) self.tm = geom.Matrix() self.numTeeth = num_teeth self.module = mod self.addendumOffset = 0.0 self.addendumMultiplier = 1.0 self.dedendumMultiplier = 1.0 self.pressureAngle = 0.34906585039886 # 20 degrees self.tipRelief = 0.05 self.color = cad.Color(128, 128, 128)
def GetTmFromCurve(curve): if curve == None: return ps = GetMinXPoint(curve) pe = GetMaxXPoint(curve) vx = pe - ps vx.Normalize() vy = ~vx o = geom.Point3D(ps.x, ps.y, 0.0) vvx = geom.Point3D(vx.x, vx.y, 0.0) vvy = geom.Point3D(vy.x, vy.y, 0.0) tm = geom.Matrix(o, vvx, vvy) return tm.Inverse()
def Scale(): centre_Pos = geom.Point3D(0, 0, 0) if cad.GetNumSelected() == 0: wx.GetApp().PickObjects('Pick objects to scale') if cad.GetNumSelected() == 0: return config = HeeksConfig() selected_items = cad.GetSelectedObjects() cad.ClearSelection(False) scale_factor = config.ReadFloat('ScaleFactor', 1.0) copy = config.ReadBool("ScaleCopy", False) pos = geom.Point3D(0, 0, 0) pos.x = config.ReadFloat("ScaleAboutPosX", 0.0) pos.y = config.ReadFloat("ScaleAboutPosY", 0.0) pos.z = config.ReadFloat("ScaleAboutPosZ", 0.0) result, pos, scale_factor, copy = InputScale(pos, scale_factor, copy, 'Scale') if not result: return config.WriteFloat("ScaleFactor", scale_factor) config.WriteBool("ScaleCopy", copy) config.WriteFloat("ScaleAboutPosX", pos.x) config.WriteFloat("ScaleAboutPosY", pos.y) config.WriteFloat("ScaleAboutPosZ", pos.z) cad.StartHistory() mat = geom.Matrix() mat.Translate(-pos) mat.Scale(scale_factor) mat.Translate(pos) for object in selected_items: if copy: if object.CanBeCopied(): object = object.MakeACopy() object.Transform(mat) cad.AddUndoably(object) else: cad.TransformUndoably(object, mat) cad.EndHistory()
def DrawPatternTriangles(self): stl = self.MakeStlSolid() outline = stl.Shadow(geom.Matrix(), True) outline.Offset(self.pattern_border) pattern = self.MakePatternedArea(outline, stl.GetBox()) for curve in pattern.GetCurves(): spans = curve.GetSpans() pts = [] for span in spans: pts.append(span.p) for i in range(2, len(pts)): self.DrawPointTriangle(pts, 0, i, i - 1)
def RotateToFace(self, object): n = self.context_face_plane.normal p = n * (-self.context_face_plane.d) x, y = n.ArbitraryAxes() face_matrix = geom.Matrix(p, x, y) inv_matrix = face_matrix.Inverse() cad.StartHistory() selected = cad.GetSelectedObjects() # if any objects are selected, move them if len(selected) > 0: for object in selected: cad.TransformUndoably(object, inv_matrix) else: # move the solid parent_body = object.GetParentBody() cad.TransformUndoably(parent_body, inv_matrix) cad.EndHistory()
def OnShadow(self, event): if not self.CheckForNumberOrMore( 1, [step.GetSolidType(), cad.OBJECT_TYPE_STL_SOLID], 'Pick one or more solids to make a shadow sketch from', 'Shadow Sketch of Solids'): return accuracy = self.InputLength('Enter Shadow Accuracy', 'Accuracy', geom.get_accuracy()) if accuracy: cad.StartHistory() geom.set_accuracy(accuracy) for object in cad.GetSelectedObjects(): stl = object.GetTris(accuracy) mat = geom.Matrix() shadow = stl.Shadow(mat, False) #shadow.Reorder() sketch = cad.NewSketchFromArea(shadow) cad.AddUndoably(sketch) cad.EndHistory()
def DrawSection(self, span): if drawing_sketches: global stl_to_add_to stl_to_add_to = geom.Stl() xmax = self.curves[1].LastVertex().p.x if xmax < 0.001: return fraction0 = span.p.x / xmax fraction1 = span.v.p.x / xmax pts0 = self.GetOrderedSectionPoints(fraction0) if pts0 == None: return pts1 = self.GetOrderedSectionPoints(fraction1) if pts1 == None: return prev_p0 = None prev_p1 = None if drawing_sketches: mirror = False else: mirror = self.values['mirror'] for p0, p1 in zip(pts0, pts1): DrawTrianglesBetweenPoints(prev_p0, prev_p1, p0, p1, mirror) prev_p0 = p0 prev_p1 = p1 if drawing_sketches: if section_index != 7: return surface = stl_to_add_to.GetFlattenedSurface() outline = surface.Shadow(geom.Matrix(), True) outline.Offset(-2.0) curves = surface.GetTrianglesAsCurveList() area_fp = tempfile.gettempdir() + '/area.dxf' for curve in curves: outline.Append(curve) outline.WriteDxf(area_fp) cad.Import(area_fp)
def DrawSection(self, span): if drawing_mode == DRAWING_MODE_SKETCHES: global stl_to_add_to stl_to_add_to = geom.Stl() perim = self.curves[1].Perim() if perim < 0.001: return fraction0 = self.curves[1].PointToPerim(span.p) / perim fraction1 = self.curves[1].PointToPerim(span.v.p) / perim pts0 = self.GetOrderedSectionPoints(fraction0) if pts0 == None: return pts1 = self.GetOrderedSectionPoints(fraction1) if pts1 == None: return prev_p0 = None prev_p1 = None if drawing_mode == DRAWING_MODE_SKETCHES: mirror = False else: mirror = self.mirror for p0, p1 in zip(pts0, pts1): self.DrawTrianglesBetweenPoints(prev_p0, prev_p1, p0, p1, mirror) prev_p0 = p0 prev_p1 = p1 if drawing_mode == DRAWING_MODE_SKETCHES: if section_index != 7: return surface = stl_to_add_to.GetFlattenedSurface() outline = surface.Shadow(geom.Matrix(), True) outline.Offset(-2.0) curves = surface.GetTrianglesAsCurveList() area_fp = tempfile.gettempdir() + '/area.dxf' for curve in curves: outline.Append(curve) outline.WriteDxf(area_fp) cad.Import(area_fp)
def ConvertHeeksFont(): chars = {} import xml.etree.ElementTree as ET this_dir = os.path.dirname(os.path.realpath(__file__)) tree = ET.parse(this_dir + '/arial font.svg') root = tree.getroot() for child in root: if child.attrib['id'] == 'layer1': for item in child: if item.tag == '{http://www.w3.org/2000/svg}g': expected_label = '{http://www.inkscape.org/namespaces/inkscape}label' scale = 1.0 if 'transform' in item.attrib: transform = item.attrib['transform'] scale = GetScaleFromTransform(transform) if expected_label in item.attrib: label = item.attrib[expected_label] if label[:4] == 'char' and len(label) == 5: c = label[4] curves = [] tris = [] pos = geom.Point(0, 0) width = 10.0 for path in item: stroke = None fill = None styles = path.attrib['style'].split(';') for style in styles: pair = style.split(':') if len(pair) == 2: if pair[0] == 'stroke': if len(pair[1]) == 7: stroke = pair[1][1:7] else: stroke = None elif pair[0] == 'fill': if len(pair[1]) == 7: fill = pair[1][1:7] else: fill = None curve = MakeCurveFromD(path.attrib['d'], c) box = curve.GetBox() if stroke == POSITION_COLOUR: pos = geom.Point(box.MinX(), box.MinY()) * scale width = (box.MaxX() - box.MinX()) * scale elif stroke != None: curves.append(curve) elif fill != None: if curve.NumVertices() == 4: # triangle curve vertices = curve.GetVertices() tris.append( Tri(vertices[0].p * scale, vertices[1].p * scale, vertices[2].p * scale)) chars[c] = Character(curves, pos, width, tris) # now write the c++ file f = open(this_dir + '/CAD/HeeksFontData.h', 'w') f.write('// HeeksFontData.h written automatically by HeeksFont.py\n\n') num_curves = [] start_curves = [] widths = [] all_curves = [] num_triangles = [] start_tris = [] all_tris = [] curve_index = 0 tri_index = 0 for i in range(32, 127): c = chr(i) pos = geom.Point(0, 0) width = 10.0 curves = [] tris = [] if c in chars: character = chars[c] curves = character.curve_list pos = character.pos width = character.width tris = character.tris n = len(curves) num_curves.append(n) start_curves.append(curve_index) nt = len(tris) num_triangles.append(nt) start_tris.append(tri_index) curve_index += n tri_index += nt mat = geom.Matrix() mat.Translate(geom.Point3D(-pos.x, -pos.y, 0)) mat.Scale(0.037037037) for curve in curves: curve.Transform(mat) all_curves.append(curve) for tri in tris: tri.Transform(mat) all_tris.append(tri) widths.append(width * 0.037037037) f.write('static int num_curves[95] = {') i = 32 for n in num_curves: f.write(str(n) + ', //' + cchr(i) + '\n') i += 1 f.write('};\n') f.write('static int start_curves[95] = {') i = 32 for n in start_curves: f.write(str(n) + ', //' + cchr(i) + '\n') i += 1 f.write('};\n\n\n') f.write('static float widths[95] = {\n') i = 32 for width in widths: f.write(str(width) + 'f, //' + cchr(i) + '\n') i += 1 f.write('};\n\n\n') point_index = 0 start_points = [] num_points = [] points = [] for curve in all_curves: vertices = curve.GetVertices() n = len(vertices) num_points.append(n) start_points.append(point_index) point_index += n for v in vertices: points.append(v.p) if len(num_points) == 0: f.write('static int* num_points;\n') else: f.write('static int num_points[' + str(len(num_points)) + '] = {') i = 0 for n in num_points: f.write(str(n) + ', //' + str(i) + '\n') i += 1 f.write('};\n') if len(start_points) == 0: f.write('static int* start_points;\n') else: f.write('static int start_points[' + str(len(start_points)) + '] = {') i = 0 for n in start_points: f.write(str(n) + ', //' + str(i) + '\n') i += 1 f.write('};\n') if len(points) == 0: f.write('static float** points;\n') else: i = 0 f.write('static float points[' + str(len(points)) + '][2] = {\n') for p in points: f.write(' {' + str(float(p.x)) + 'f, ' + str(float(p.y)) + 'f}, //' + str(i) + '\n') i += 1 f.write('};\n') f.write('static int num_triangles[95] = {') i = 32 for n in num_triangles: f.write(str(n) + ', //' + cchr(i) + '\n') i += 1 f.write('};\n') f.write('static int start_tris[95] = {') i = 32 for n in start_tris: f.write(str(n) + ', //' + cchr(i) + '\n') i += 1 f.write('};\n\n\n') i = 0 f.write('static float tris[' + str(len(all_tris)) + '][6] = {\n') for t in all_tris: f.write(' {' + str(float(t.p0.x)) + 'f, ' + str(float(t.p0.y)) + 'f, ' + str(float(t.p1.x)) + 'f, ' + str(float(t.p1.y)) + 'f, ' + str(float(t.p2.x)) + 'f, ' + str(float(t.p2.y)) + 'f}, //' + str(i) + '\n') i += 1 f.write('};\n') f.close() print('successfully created HeeksFont.h')
def RenderGrid2(cad, view_point, max_number_across, in_between_spaces, miss_main_lines, bg, cc, brightness, plane_mode): zval = 0.5 size = view_point.viewport.GetViewportSize() sp = [] sp.append(geom.Point3D(0, 0, zval)) sp.append(geom.Point3D(size.GetWidth(), 0, zval)) sp.append(geom.Point3D(size.GetWidth(), size.GetHeight(), zval)) sp.append(geom.Point3D(0, size.GetHeight(), zval)) vx, vy, plane_mode2 = view_point.GetTwoAxes(False, plane_mode) datum = geom.Point3D(0, 0, 0) orimat = cad.GetDrawMatrix(False) datum.Transform(orimat) orimat = geom.Matrix(datum, vx, vy) unit_forward = view_point.forwards_vector().Normalized() plane_dp = math.fabs( geom.Point3D(0, 0, 1).Transformed(orimat) * unit_forward) if plane_dp < 0.3: return plane = geom.Plane( geom.Point3D(0, 0, 0).Transformed(orimat), geom.Point3D(0, 0, 1).Transformed(orimat)) for i in range(0, 4): p1 = view_point.glUnproject(sp[i]) sp[i].z = 0.0 p2 = view_point.glUnproject(sp[i]) if p1.Dist(p2) < 0.00000000001: return line = geom.Line(p1, p2) pnt = line.IntersectPlane(plane) if pnt != None: sp[i].x = (pnt * vx) - (datum * vx) sp[i].y = (pnt * vy) - (datum * vy) sp[i].z = 0.0 b = geom.Box3D() for i in range(0, 4): b.InsertPoint(sp[i].x, sp[i].y, sp[i].z) width = b.Width() height = b.Height() biggest_dimension = None if height > width: biggest_dimension = height else: biggest_dimension = width widest_spacing = biggest_dimension / max_number_across dimmer = False dimness_ratio = 1.0 spacing = None if cad.draw_to_grid: spacing = cad.digitizing_grid if miss_main_lines == False: spacing = spacing * 10 if spacing < 0.0000000001: return if biggest_dimension / spacing > max_number_across * 1.5: return if biggest_dimension / spacing > max_number_across: dimmer = True dimness_ratio = (max_number_across * 1.5 - biggest_dimension / spacing) / (max_number_across * 0.5) else: l = math.log10(widest_spacing / cad.view_units) intl = int(l) if l > 0: intl = intl + 1 spacing = math.pow(10.0, intl) * cad.view_units if cad.grid_mode == 3: dimmer = True dimness_ratio = dimness_ratio * plane_dp dimness_ratio = dimness_ratio * plane_dp ext2d = [b.x[0], b.x[1], b.x[3], b.x[4]] for i in range(0, 4): intval = int(ext2d[i] / spacing) if i < 2: if ext2d[i] < 0: intval -= 1 elif ext2d[i] > 0: intval += 1 ext2d[i] = intval * spacing if cc: col = HeeksColor(cc.red, cc.green, cc.blue) if cad.grid_mode == 3: if plane_mode2 == 0: col.green = int(0.6 * float(bg.green)) elif plane_mode2 == 1: col.red = int(0.9 * float(bg.red)) else: col.blue = bg.blue if dimmer: d_brightness = float(brightness) * dimness_ratio uc_brightness = int(d_brightness) glColor4ub(col.red, col.green, col.blue, uc_brightness) else: glColor4ub(col.red, col.green, col.blue, brightness) glBegin(GL_LINES) extra = 0.0 if in_between_spaces: extra = spacing * 0.5 x = ext2d[0] - extra while x < ext2d[2] + extra: if miss_main_lines: xr = x / spacing / 5 temp = xr if temp > 0: temp += 0.5 else: temp -= 0.5 temp = int(temp) temp = float(temp) if math.fabs(xr - temp) < 0.1: x += spacing continue temp = datum + (vx * x) + (vy * ext2d[1]) glVertex3d(temp.x, temp.y, temp.z) temp = datum + (vx * x) + (vy * ext2d[3]) glVertex3d(temp.x, temp.y, temp.z) x += spacing y = ext2d[1] - extra while y < ext2d[3] + extra: if miss_main_lines: yr = y / spacing / 5 temp = yr if temp > 0: temp += 0.5 else: temp -= 0.5 temp = int(temp) temp = float(temp) if math.fabs(yr - temp) < 0.1: y += spacing continue temp = datum + (vx * ext2d[0]) + (vy * y) glVertex3d(temp.x, temp.y, temp.z) temp = datum + (vx * ext2d[2]) + (vy * y) glVertex3d(temp.x, temp.y, temp.z) y += spacing glEnd()
def Rotate(copy=False): #rotation axis - Z axis by default axis_Dir = geom.Point3D(0, 0, 1) line_Pos = geom.Point3D(0, 0, 0) if cad.GetNumSelected() == 0: wx.GetApp().PickObjects('Pick objects to rotate') if cad.GetNumSelected() == 0: return config = HeeksConfig() ncopies = None if copy: ncopies = config.ReadInt('RotateNumCopies', 1) RemoveUncopyable() if cad.GetNumSelected() == 0: return selected_items = cad.GetSelectedObjects() cad.ClearSelection(False) angle = config.ReadFloat('RotateAngle', 90.0) # enter angle, plane and position axis = geom.Point3D(0, 0, 1) pos = geom.Point3D(0, 0, 0) axis.x = config.ReadFloat("RotateAxisX", 0.0) axis.y = config.ReadFloat("RotateAxisY", 0.0) axis.z = config.ReadFloat("RotateAxisZ", 1.0) pos.x = config.ReadFloat("RotatePosX", 0.0) pos.y = config.ReadFloat("RotatePosY", 0.0) pos.z = config.ReadFloat("RotatePosZ", 0.0) axial_shift = config.ReadFloat('RotateAxialShift', 0.0) result, angle, axis, pos, ncopies, axial_shift = InputAngleWithPlane( angle, axis, pos, ncopies, axial_shift, 'Rotate') if not result: return if copy: if ncopies < 1: return config.WriteInt("RotateNumCopies", ncopies) config.WriteFloat("RotateAngle", angle) config.WriteFloat("RotateAxialShift", axial_shift) config.WriteFloat("RotateAxisX", axis.x) config.WriteFloat("RotateAxisY", axis.y) config.WriteFloat("RotateAxisZ", axis.z) config.WriteFloat("RotatePosX", pos.x) config.WriteFloat("RotatePosY", pos.y) config.WriteFloat("RotatePosZ", pos.z) cad.StartHistory() if copy: for i in range(0, ncopies): mat = geom.Matrix() mat.Translate(-pos) mat.RotateAxis(angle * 0.0174532925199433 * (i + 1), axis) mat.Translate(pos) for object in selected_items: new_object = object.MakeACopy() object.GetOwner().Add(new_object) cad.TransformUndoably(new_object, mat) else: mat = geom.Matrix() mat.Translate(-pos) mat.RotateAxis(angle * 0.0174532925199433, axis) mat.Translate(pos) for object in selected_items: cad.TransformUndoably(object, mat) cad.EndHistory()
def Translate(copy=False): if cad.GetNumSelected() == 0: wx.GetApp().PickObjects('Pick objects to move') if cad.GetNumSelected() == 0: return config = HeeksConfig() ncopies = None if copy: ncopies = config.ReadInt('TranslateNumCopies', 1) RemoveUncopyable() if cad.GetNumSelected() == 0: return selected_items = cad.GetSelectedObjects() cad.ClearSelection(False) fromp = geom.Point3D() to = geom.Point3D() fromp.x = config.ReadFloat("TranslateFromX", 0.0) fromp.y = config.ReadFloat("TranslateFromY", 0.0) fromp.z = config.ReadFloat("TranslateFromZ", 0.0) to.x = config.ReadFloat("TranslateToX", 0.0) to.y = config.ReadFloat("TranslateToY", 0.0) to.z = config.ReadFloat("TranslateToZ", 0.0) result, fromp, to, ncopies = InputFromAndTo(fromp, to, ncopies, 'Move Translate') if not result: return if copy: if ncopies < 1: return config.WriteInt("TranslateNumCopies", ncopies) config.WriteFloat("TranslateFromX", fromp.x) config.WriteFloat("TranslateFromY", fromp.y) config.WriteFloat("TranslateFromZ", fromp.z) config.WriteFloat("TranslateToX", to.x) config.WriteFloat("TranslateToY", to.y) config.WriteFloat("TranslateToZ", to.z) cad.StartHistory() if copy: for i in range(0, ncopies): mat = geom.Matrix() mat.Translate((to - fromp) * (i + 1)) for object in selected_items: new_object = object.MakeACopy() object.GetOwner().Add(new_object) cad.TransformUndoably(new_object, mat) else: mat = geom.Matrix() mat.Translate(to - fromp) for object in selected_items: cad.TransformUndoably(object, mat) cad.EndHistory()