def test_to_step(self): s1 = cm.box(1.0, 2.0, 3.0).subshapes('Shell')[0] r1 = s1.area() s1.to_step('tmp.stp') s2 = cm.from_step('tmp.stp') r2 = s2.area() self.assert_(close(r1, 22.0) and close(r2, 22.0))
def test_to_step(self): s1 = cm.box(1.0, 2.0, 3.0) r1 = s1.volume() s1.to_step('tmp.stp') s2 = cm.from_step('tmp.stp') r2 = s2.volume() self.assert_(close(r1, 6.0) and close(r2, 6.0))
def test_to_step(self): s1 = cm.plane(cm.ngon(1.0, 3)) r1 = s1.area() s1.to_step('tmp.stp') s2 = cm.from_step('tmp.stp') r2 = s2.area() self.assert_(close(r1, r2))
def test_to_step(self): s1 = cm.box(1.0, 2.0, 3.0).subshapes('shell')[0] r1 = s1.area() s1.to_step('tmp.stp') s2 = cm.from_step('tmp.stp') r2 = s2.area() self.assert_(close(r1, 22.0) and close(r2, 22.0))
def get_solid_from_nodes(self, lnodes): """ get a solid from nodes Parameters ---------- lnodes : list of nodes or -1 for all Returns ------- s : node solid Notes ----- If the assembly file has extension .stp it means that the analysis has not been done. After the analysis a directory has been created, it contains all the .stp file of the parts and a .json file which contains the graph information. """ if lnodes == -1: lnodes = self.node.keys() rep = self.get_dirname() lfiles = [str(self.node[k]['name']) + '.stp' for k in lnodes] lV = [self.node[k]['V'] for k in lnodes] lflip = [self.node[k]['flip'] for k in lnodes] lpc = [self.node[k]['pc'] for k in lnodes] solid = cm.Solid([]) for k, s in enumerate(lfiles): filename = os.path.join(rep, s) shp = cm.from_step(filename) # assert(np.allclose(np.array(shp.center()),0)),pdb.set_trace() V = lV[k] shp.unitary(V) if lflip[k]: shp.mirrorz() shp.translate(lpc[k]) solid = solid + shp # print(k,solid.shape.Orientation(),solid.volume(),shp.volume()) return solid
def view_assembly_nodes(x, node_index=-1): """ Parameters ---------- x : An Assembly Graph node_index : a list of Assembly nodes (-1 : all nodes) Notes ----- An Assembly is a graph Each node of an assembly has attached + a filename describing a solid in its own local frame + a quaternion for solid orientation in the global frame + a translation vector for solid placement in the global frame This function takes an Assembly as argument and produces the view in the global frame. """ if type(node_index) == int: if node_index == -1: node_index = x.node.keys() else: node_index = [node_index] assert (max(node_index) <= max(x.node.keys())), "Wrong node index" if x.serialized: s.unserialize() # viewer initialisation ccad_viewer = cd.view() # get the list of all shape associated with Assembly x # # This is for debug purpose. # In the final implementation. # The assembly structure is not supposed to save shapes themselves # but only references to files (.py or .step) # #lshapes1 = [x.node[k]['shape'] for k in node_index] # get the list of all filename associated with Assembly x lfiles = [str(x.node[k]['name']) + '.stp' for k in node_index] # select directory where node files are saved # temporary # fileorig = x.origin.split('.')[0] rep = os.path.join('.', fileorig) # get the local frame shapes from the list .step files lshapes2 = [cm.from_step(os.path.join(rep, s)) for s in lfiles] # get unitary matrix and translation for global frame placement lV = [x.node[k]['V'] for k in node_index] lptm = [x.node[k]['ptc'] for k in node_index] #lbmx = [x.node[k]['bmirrorx'] for k in node_index] # # iter on selected local shapes and apply the graph stored geometrical transformation sequence # 1 : rotation # 2 : translation # for k, shp in enumerate(lshapes2): V = lV[k] shp.transform(V) # if 'mx' in x.node[k]: # if x.node[k]['mx']: # print(k,"mx") # shp.mirrorx() # if 'my' in x.node[k]: # if x.node[k]['my']: # print(k,"my") # shp.mirrory() # if 'mz' in x.node[k]: # if x.node[k]['mz']: # print(k,"mz") # shp.mirrorz() #shp.rotate(np.array([0,0,0]),vec,-ang) shp.translate(lptm[k]) shp.foreground = (1, 1, 0.5) # create a solid with the transformed shapes solid = cm.Solid(lshapes2) ccad_viewer.set_background((1, 1, 1)) # White ccad_viewer.display(solid, transparency=0.5, material='copper') cd.start() return lshapes2, lV, lptm
def __init__(self, step_file_path, anchors=None): super(GeometryNode, self).__init__() assert exists(step_file_path) self.step_file_path = step_file_path self._anchors = anchors self._shape = cm.from_step(step_file_path)
def view(model): display, start_display, add_menu, add_function_to_menu = SimpleGui.init_display( ) display.DisplayShape(model.shape, update=True) start_display() # # read a file from the OSV parts # The goal is to decomposed this object in a graph of simpler objects # # 1) get a solid from step solid = cm.from_step('level1/ASM0001_ASM_1_ASM.stp') #solid = cm.from_step('Duplex_A_20110907.ifc') #solid = cm.from_step('level1/MOTORIDUTTORE_ASM.stp') # 2) construct entity from solid entity = ce.entity(solid) # # An entity is a solid and a graph # #lshell = t1.subshapes('shell') #pc = np.array(t1.center()) #t2 = t1.copy() #t2.translate(-pc) # #u = cm.solid(lshell) #lvertex = lshell[2].subshapes('vertex') #ledge = lshell[2].subshapes('edge')
#s1=cm.sphere(1.0) #s1.translate(np.array([1,12,3])) #b1 = cm.box(1,2,5) #s = s1-b1 def view(model): display, start_display, add_menu, add_function_to_menu = SimpleGui.init_display() display.DisplayShape(model.shape, update = True) start_display() # # read a file from the OSV parts # The goal is to decomposed this object in a graph of simpler objects # # 1) get a solid from step solid = cm.from_step('level1/ASM0001_ASM_1_ASM.stp') #solid = cm.from_step('Duplex_A_20110907.ifc') #solid = cm.from_step('level1/MOTORIDUTTORE_ASM.stp') # 2) construct entity from solid entity = ce.entity(solid) # # An entity is a solid and a graph # #lshell = t1.subshapes('shell') #pc = np.array(t1.center()) #t2 = t1.copy() #t2.translate(-pc) # #u = cm.solid(lshell) #lvertex = lshell[2].subshapes('vertex') #ledge = lshell[2].subshapes('edge')
def from_step(self, filename): """ creates an non hierarchical assembly with a solid per node Parameters ---------- filename : str step file name Notes ----- Creates a node per valid solid (check TRUE) This assembly is not clean it contains a lot of information in each node. pcloud : pc.Pointcloud (centered and ordered point cloud) shape : cm.Solid """ self.solid = cm.from_step(filename) self.isclean = False # # if it contains, An Assembly: # is clean : filename and transformation # is not clean : pointcloud and shape # # self.G = nx.DiGraph() self.origin = filename shells = self.solid.subshapes("Shell") # logger.info("%i shells in assembly" % len(shells)) self.nnodes = 0 for _, shell in enumerate(shells): solid = cm.Solid([shell]) # check the shell corresponds to a cosed solid if solid.check(): # logger.info("Dealing with shell nb %i" % k) # pcloud = np.array([[]]) # pcloud.shape = (3, 0) # pcloud = pc.PointCloud() # pcloud = pcloud.from_solid(solid) # vertices = shell.subshapes("Vertex") # logger.info("%i vertices found for direct method") # for vertex in vertices: # point = np.array(vertex.center())[:, None] # pcloud = np.append(pcloud, point, axis=1) # pcloud = pcloud + point # add shape to graph if shell not degenerated # Npoints = pcloud.p.shape[0] # if ((shell.area()>0) and Npoints >=3): if shell.area() > 0: # pcloud.centering() # pcloud.ordering() # the stored point cloud is centered and ordered # self.add_node(self.nnodes, # pcloud=pcloud, # shape=solid, # volume=solid.volume(), # assembly=False) self.add_node(self.nnodes, shape=solid, volume=solid.volume(), assembly=False) self.pos[self.nnodes] = solid.center() self.nnodes += 1
def write_components(self): r""" Write individual components of the assembly Notes ----- Write unique components to their own step files in a subdirectory of the folder containing the original file """ if os.path.isfile(self.origin): # directory = os.path.dirname(self.origin) # basename = os.path.basename(self.origin) # subdirectory = os.path.join(directory, # os.path.splitext(basename)[0]) subdirectory = self.get_dirname() if not os.path.isdir(subdirectory): os.mkdir(subdirectory) else: msg = "The components of the assembly should already exist" raise ValueError(msg) # get the list of step files or json files in subdirectory filelist = [ f for f in os.listdir(subdirectory) if (f.endswith(".stp") or f.endswith(".json")) ] for f in filelist: os.remove(os.path.join(subdirectory, f)) # creates dataframe self.df_nodes = pd.DataFrame(columns=('name', 'count', 'nodes', 'volume', 'assembly')) self.dnodes = {} for k in self.node: # calculate point cloud signature # pcloudk = self.node[k]['pcloud'] # # solidk : uncentered solid # solidk_centered : centered solid # solidk = self.node[k]['shape'] ptc = np.array(solidk.center()) # warning : center of gravity is obtained # from solid not from pointcloud solidk_centered = cm.translated(solidk, -ptc) pcloudk = pc.PointCloud() pcloudk = pcloudk.from_solid(solidk_centered) Npoints = pcloudk.p.shape[0] pcloudk.sorting() pcloudk.ordering() pcloudk.signature() V = pcloudk.V Npoints = pcloudk.Npoints self.node[k]['pc'] = ptc self.node[k]['flip'] = False self.node[k]['Npoints'] = Npoints if np.linalg.det(V) > 0: self.node[k]['V'] = V else: V[:, 2] = -V[:, 2] self.node[k]['V'] = V self.node[k]['flip'] = True # V is a assert as a rotation if np.linalg.det(V) <= 0: raise AssertionError("") assembly = self.node[k]['assembly'] # # Transfer solidk to the origin # # The order of the geometrical operations is important # solidk.translate(-ptc) if self.node[k]['flip']: solidk.mirrorz() solidk.unitary(V.T) # assert(np.allclose(solidk.center(),0)) # # Point cloud of the solid centered and transformed # pcloudk_transformed = pc.PointCloud() pcloudk_transformed = pcloudk_transformed.from_solid(solidk) pcloudk_transformed.sorting() pcloudk_transformed.ordering() pcloudk_transformed.signature() self.node[k]['sig'] = pcloudk_transformed.sig name = pcloudk_transformed.name self.node[k]['name'] = name self.node[k]['pcloud'] = pcloudk_transformed filename = pcloudk_transformed.name + ".stp" filename = os.path.join(subdirectory, filename) lnames = self.df_nodes['name'].values # if not os.path.isfile(filename): if not (name in lnames): # save translated transformed unique shape to filename solidk.to_step(filename) index = len(self.df_nodes) self.df_nodes = self.df_nodes.set_value(index, 'name', name) self.df_nodes = self.df_nodes.set_value( index, 'volume', solidk.volume()) self.df_nodes = self.df_nodes.set_value(index, 'count', 1) self.df_nodes = self.df_nodes.set_value(index, 'nodes', [k]) self.df_nodes = self.df_nodes.set_value( index, 'assembly', assembly) else: # get solid from origin file # solid_orig = cm.from_step(filename) # TODO : why not used? _ = cm.from_step(filename) # transform it around origin # node_solid = self.df_nodes[self.df_nodes['name']==name]['nodes'].values[0][0] # print("Node_solid",k,node_solid) # solid.unitary(V_orig) # pcloud_orig = pc.PointCloud() # pcloud_orig = pcloud_orig.from_solid(solid_orig) # pcloud_orig.sorting() # pcloud_orig.ordering() # d0,d1 = pcloud_orig.distance(pcloudk_transformed) # S = np.dot(V.T,V_orig) # T1 = np.dot(pcloud_orig.p.T,pcloudk_transformed.p) # T2 = np.dot(pcloudk_transformed.p.T,pcloud_orig.p) # print(k, d0, d1) # SI = np.diag(1./Sk) # U3 = Uk[:,:3] # H1 = np.dot(pcloud_orig.p.T,U3) # H2 = np.dot(H1,SI) # T3 = np.dot(H2,Vk) # if k==7: # pdb.set_trace() # self.node[k]['V'] = V_orig # print(d0,d1) # if pcloudk != pcloud_orig: # V1 = pcloud_orig.get_transform(pcloudk) # V2 = pcloudk.get_transform(pcloud_orig) # fig,ax = pcloudk.show(c = 'r') # fig,ax = pcloud_orig.show(fig=fig, ax=ax, c='b') # plt.show() # pdb.set_trace() dfname = self.df_nodes[self.df_nodes['name'] == name] dfname['count'] += 1 dfname.iloc[0]['nodes'].append(k) self.df_nodes[self.df_nodes['name'] == name] = dfname self.dnodes[k] = index