python/lib/python3.6/site-packages/viewscad/renderer.py

如果你使用的openscad版本过旧(ubuntu16.04 是openscad2015)

通过python代码viewscad调用的时候,可能会出现错误,需要新版本的openscad

你可以修改renderer.py

    def _try_detect_openscad_exec(self):self.openscad_exec = Noneplatfm = platform.system()if platfm == 'Linux':self._try_executable('/usr/bin/openscad')if self.openscad_exec is None:#self._try_executable('/usr/local/bin/openscad')self._try_executable('~/下载/OpenSCAD-2021.01-x86_64.AppImage')elif platfm == 'Darwin':self._try_executable('/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD')elif platfm == 'Windows':self._try_executable(os.path.join(os.environ.get('Programfiles(x86)','C:'),'OpenSCAD\\openscad.exe'))

https://stackoverflow.com/questions/60562858/best-libraries-for-openscad

0)
https://openscad.org/libraries.html

1)
https://github.com/cznewt/openscad-model-library
https://openscad-model-library.readthedocs.io/en/latest/primitives.html#bolts-and-nuts

2)
https://github.com/revarbat/BOSL
https://github.com/revarbat/BOSL/wiki

3)
https://github.com/revarbat/BOSL2
https://github.com/revarbat/BOSL2/wiki

4)
https://github.com/Irev-Dev/Round-Anything
https://kurthutten.com/blog/round-anything-a-pragmatic-approach-to-openscad-design/

5)
https://github.com/nophead/NopSCADlib
https://github.com/nophead/NopSCADlib/blob/master/readme.md

6)
https://github.com/boltsparts/BOLTS   推荐这个
https://www.bolts-library.org/en/index.html

7)
https://github.com/JustinSDK/dotSCAD

8)
https://github.com/openscad/MCAD
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/MCAD#Overview_of_MCAD_Library

9)
https://www.thingiverse.com/thing:3215997

10)
https://github.com/openscad/list-comprehension-demos

11)
https://github.com/davidson16807/relativity.scad

模型下载:

GitHub - rcolyer/threads-scad: OpenSCAD threading library

GitHub - GillesBouissac/agentscad: My utilities for OpenSCAD

GitHub - openscad/MCAD: OpenSCAD Parametric CAD Library (LGPL 2.1)

GitHub - JohK/nutsnbolts: A OpenSCAD library that allows for simple creation of nuts and bolts and respective nut catches and screw holes

https://www.bolts-library.org/en/index.html

https://github.com/boltsparts/BOLTS

https://www.bolts-library.org/en/parts/index.html

Metric bolts with OpenSCAD by Claymore - Thingiverse

Nuts and Bolts v1.95 OpenSCAD library by biomushroom - Thingiverse

OpenSCAD教程-初学者的5个简单步骤

OpenSCAD教程-初学者的5个简单步骤

OpenSCAD中使用include或use引入外部库

OpenSCAD中使用include或use引入外部库_weixin_34221112的博客-CSDN博客

hex_head2.scad

$fn=100;module hex_head(diameter,height) {intersection() {union() {translate([0,0,0.801*height])cylinder(d1=diameter,d2=0.8*diameter,h=0.2*height);cylinder(d=diameter,h=0.801*height);}cylinder(d=diameter,h=height,$fn=6);}
}module washer(outside_diameter,inside_diameter,height) {difference() {cylinder(d=outside_diameter,h=height);translate([0,0,-0.01])cylinder(d=inside_diameter,h=height+0.02);}
}module steel_plate(side,thickness) {translate([-side/2,-side/2,0])cube([side,side,thickness]);
}module screw(diameter,height) {cylinder(d=diameter, h=height);
}module hex_head2(tran_init,plate_side,plate_height,washer_out_diam,washer_in_diam,washer_height,bolt_height,bolt_diam,bolt_tran,bolt_rot,screw_diam,screw_height){union(){translate([0,0,tran_init])steel_plate(plate_side,plate_height);translate([0,0,tran_init+plate_height]) washer(washer_out_diam, washer_in_diam, washer_height);translate([0,0,tran_init+plate_height+washer_height+bolt_tran])rotate([0,0,bolt_rot])hex_head(bolt_diam, bolt_height);translate([0,0,tran_init+plate_height+washer_height]) screw(screw_diam, screw_height);    }
}//平面距离坐标原点的高度
tran_init = 0;//底平面参数
plate_side   = 70;
plate_height = 2;//垫片参数
washer_out_diam = 50;
washer_in_diam = 0;
washer_height = 3;//螺母参数
bolt_height = 22; //大小-高度
bolt_diam   = 35; //大小-宽度
bolt_tran   = 20; //上下-高度
bolt_rot    = 130; // degrees//螺柱参数
screw_diam   = 16;
screw_height = 44;hex_head2(tran_init,plate_side,plate_height,washer_out_diam,washer_in_diam,washer_height,bolt_height,bolt_diam,bolt_tran,bolt_rot,screw_diam,screw_height);

demo_bolt_002.py

# python3.8
# -*- coding: utf-8 -*-
# ---
# @Software: PyCharm
# @File: demo_bolt_002.py
# @Author: ---
# @Institution: BeiJing, China
# @E-mail: lgdyangninghua@163.com
# @Site:
# @Time: 5月 12, 2021
# ---
import argparse
from solid import *
from solid.utils import *
import viewscad
import open3d as o3d
import os
import pathlibscad_parameter={#平面距离坐标原点的高度'tran_init': 0,#底平面参数'plate_side': 70,'plate_height': 2,#垫片参数'washer_out_diam': 50,'washer_in_diam': 0,'washer_height': 3,#螺母参数'bolt_height': 22, #大小-高度'bolt_diam': 35, #大小-宽度'bolt_tran': 15, #上下-高度'bolt_rot': 15, #角度#螺柱参数'screw_diam': 16,'screw_height': 44,
}def mkdir_os(path):if not os.path.exists(path):os.makedirs(path)def main(args):scad_path = pathlib.Path(args.input_scad)if not scad_path.is_file():print("input_scad error")returnmkdir_os(args.output_stl_folder)mkdir_os(args.output_ply_folder)scad_F = import_scad(args.input_scad)index = 0count = scad_parameter['screw_height'] * (180/10)for nut_height in range(0, scad_parameter['screw_height'], 1):for nut_angle in range(0, 180, 10):index += 1print(index, "/", count)save_stl_name = "bolt1_index{:0>5d}_nut_height-{}_nut_angle-{}.stl".format(index, nut_height, nut_angle)save_ply_name = "bolt1_index{:0>5d}_nut_height-{}_nut_angle-{}.ply".format(index, nut_height, nut_angle)stl_path = os.path.join(args.output_stl_folder, save_stl_name)ply_path = os.path.join(args.output_ply_folder, save_ply_name)scad_model = scad_F.hex_head2(tran_init=scad_parameter['tran_init'],plate_side=scad_parameter['plate_side'],plate_height=scad_parameter['plate_height'],washer_out_diam=scad_parameter['washer_out_diam'],washer_in_diam=scad_parameter['washer_in_diam'],washer_height=scad_parameter['washer_height'],bolt_height=scad_parameter['bolt_height'],bolt_diam=scad_parameter['bolt_diam'],bolt_tran=nut_height,bolt_rot=nut_angle,screw_diam=scad_parameter['screw_diam'],screw_height=scad_parameter['screw_height'])v_rander = viewscad.Renderer()v_rander.render(scad_model, outfile=stl_path)#pymeshlabimport pymeshlab as mlms = ml.MeshSet()ms.load_new_mesh(stl_path)filename_mesh_out = os.path.join(args.output_stl_folder, "pymeshlab_"+save_stl_name)ms.save_current_mesh(filename_mesh_out)#这里之所以使用pymeshlab保存的stl,是因为open3d0.9.0有点问题,只能打开二进制的stl#https://github.com/intel-isl/Open3D/issues/2479#open3dmesh_bolt = o3d.io.read_triangle_mesh(filename_mesh_out)#mesh_bolt.paint_uniform_color([0, 0, 1])pcd_mesh_bolt = mesh_bolt.sample_points_poisson_disk(number_of_points=15000)#pcd_mesh_bolt.paint_uniform_color([1, 1, 0])#print('pcd_mesh_bolt:', pcd_mesh_bolt)pcd_mesh_bolt = pcd_mesh_bolt.voxel_down_sample(voxel_size=1)#print('pcd_mesh_bolt', pcd_mesh_bolt)o3d.io.write_point_cloud(ply_path, pcd_mesh_bolt)if __name__ == "__main__":parser = argparse.ArgumentParser(description="creat bolt")parser.add_argument('-if',"--input_scad",default='./hex_head2.scad',help="set input scad file")parser.add_argument('-os',"--output_stl_folder",default='./result_stl/',help="set output stl folder")parser.add_argument('-op',"--output_ply_folder",default='./result_ply/',help="set output ply folder")args = parser.parse_args()if args.input_scad is None:parser.print_help()exit()main(args)'''
https://openscad.org/
https://github.com/nickc92/ViewSCAD
https://github.com/SolidCode/SolidPython
https://github.com/cnr-isti-vclab/PyMeshLabpython -mpip install open3d==0.9.0
sudo apt-get install openscad (2015.03-1+dfsg-3)
solid                  0.2.0
solidpython            0.4.2
python -mpip install solid==0.2.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
python -mpip install solidpython==0.4.2 -i https://pypi.tuna.tsinghua.edu.cn/simplejupyter可视化
python -mpip install viewscad==0.2.0
安装插件:
jupyter labextension install @jupyter-widgets/jupyterlab-manager
https://pypi.org/project/jupyter-openscad-kernel/https://pymeshlab.readthedocs.io/en/latest/
python -mpip install pymeshlab==0.2
'''

demo_bolt_003.py

带标签的数据生成:

# python3.8
# -*- coding: utf-8 -*-
# ---
# @Software: PyCharm
# @File: demo_bolt_002.py
# @Author: ---
# @Institution: BeiJing, China
# @E-mail: lgdyangninghua@163.com
# @Site:
# @Time: 5月 12, 2021
# ---
import argparse
from solid import *
from solid.utils import *
import viewscad
import open3d as o3d
import os
import pathlib
import copy
import numpy as npHEADER = '''\
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z label
SIZE 4 4 4 4
TYPE F F F I
COUNT 1 1 1 1
WIDTH {}
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS {}
DATA ascii
'''
def write_pcd_fun1(points, save_pcd_path):n = len(points)lines = []for i in range(n):x, y, z, label = points[i]lines.append('{:.6f} {:.6f} {:.6f} {}'.format(x, y, z, label))with open(save_pcd_path, 'w') as f:f.write(HEADER.format(n, n))f.write('\n'.join(lines))
def write_pcd_fun2(points, save_pcd_path):with open(save_pcd_path, 'w') as f:f.write(HEADER.format(len(points), len(points)) + '\n')np.savetxt(f, points, delimiter=' ', fmt='%f %f %f %d')#https://blog.csdn.net/weixin_48994268/article/details/115682269
#open3d连续读取pcd文件及实现点云视角转换
def save_view_point(pcd, filename):vis = o3d.visualization.Visualizer()vis.create_window(window_name='pcd', width=800, height=600)vis.add_geometry(pcd)vis.run()  # user changes the view and press "q" to terminateparam = vis.get_view_control().convert_to_pinhole_camera_parameters()o3d.io.write_pinhole_camera_parameters(filename, param)vis.destroy_window()
def load_view_point(pcd, filename):vis = o3d.visualization.Visualizer()vis.create_window(window_name='pcd', width=800, height=600)ctr = vis.get_view_control()param = o3d.io.read_pinhole_camera_parameters(filename)vis.add_geometry(pcd)ctr.convert_from_pinhole_camera_parameters(param)vis.run()vis.destroy_window()scad_parameter={#平面距离坐标原点的高度'tran_init': 0,#底平面参数'plate_side': 70,'plate_height': 1,#垫片参数'washer_out_diam': 50,'washer_in_diam': 0,'washer_height': 2,#螺母参数'bolt_height': 22, #大小-高度'bolt_diam': 35, #大小-宽度'bolt_tran': 15, #上下-高度'bolt_rot': 15, #角度#螺柱参数'screw_diam': 16,'screw_height': 44,
}label_dict = {"other": 0, #washer"stud": 1,"plane": 2,"nut": 3,
}def mkdir_os(path):if not os.path.exists(path):os.makedirs(path)def main(args):scad_path = pathlib.Path(args.input_scad)if not scad_path.is_file():print("input_scad error")returnmkdir_os(args.output_stl_folder)mkdir_os(args.output_ply_folder)scad_F = import_scad(args.input_scad)index = 0count = scad_parameter['screw_height'] * (180/10)for nut_height in range(0, scad_parameter['screw_height'], 1):for nut_angle in range(0, 180, 10):index += 1print(index, "/", count)save_stl_name = "bolt1_index{:0>5d}_nut_height-{}_nut_angle-{}.stl".format(index, nut_height, nut_angle)save_ply_name = "bolt1_index{:0>5d}_nut_height-{}_nut_angle-{}.ply".format(index, nut_height, nut_angle)stl_path = os.path.join(args.output_stl_folder, save_stl_name)ply_path = os.path.join(args.output_ply_folder, save_ply_name)scad_model = scad_F.hex_head2(tran_init=scad_parameter['tran_init'],plate_side=scad_parameter['plate_side'],plate_height=scad_parameter['plate_height'],washer_out_diam=scad_parameter['washer_out_diam'],washer_in_diam=scad_parameter['washer_in_diam'],washer_height=scad_parameter['washer_height'],bolt_height=scad_parameter['bolt_height'],bolt_diam=scad_parameter['bolt_diam'],bolt_tran=nut_height,bolt_rot=nut_angle,screw_diam=scad_parameter['screw_diam'],screw_height=scad_parameter['screw_height'])#分开生成形成label#垫圈+otherwasher = copy.deepcopy(scad_model)washer.params["plate_height"] = 0washer.params["bolt_height"] = 0washer.params["screw_height"] = 0#螺柱stud = copy.deepcopy(scad_model)stud.params["plate_height"] = 0stud.params["washer_height"] = 0stud.params["bolt_height"] = 0#底平面plane = copy.deepcopy(scad_model)plane.params["washer_height"] = 0plane.params["bolt_height"] = 0plane.params["screw_height"] = 0#螺母nut = copy.deepcopy(scad_model)nut.params["plate_height"] = 0nut.params["washer_height"] = 0nut.params["screw_height"] = 0model_list = [washer, stud, plane, nut]mesh_list = []color_list = [[1, 0, 0],[0, 1, 0],[0, 0, 1],[1, 1, 0]]for ind, mod in enumerate(model_list):v_rander = viewscad.Renderer()v_rander.render(mod, outfile=stl_path) #这里已经保存了stl,但是是ascii format#pymeshlabimport pymeshlab as mlms = ml.MeshSet()ms.load_new_mesh(stl_path)filename_mesh_out = os.path.join(args.output_stl_folder, "pymeshlab_"+save_stl_name)ms.save_current_mesh(filename_mesh_out)#这里之所以使用pymeshlab保存的stl,是因为open3d0.9.0有点问题,只能打开二进制的stl#https://github.com/intel-isl/Open3D/issues/2479#open3dmesh_bolt = o3d.io.read_triangle_mesh(filename_mesh_out)mesh_bolt.paint_uniform_color(color_list[ind])mesh_list.append(mesh_bolt)model = mesh_list[0] + mesh_list[1] + mesh_list[2] + mesh_list[3]model_point = model.sample_points_poisson_disk(number_of_points=15000)print('model_point:', model_point)model_point = model_point.voxel_down_sample(voxel_size=1)print('model_point', model_point)#螺柱在螺母中的也会显示# o3d.visualization.draw_geometries([#model,#                                    model_point,#                                    #model_point.get_axis_aligned_bounding_box(),#                                    #model.get_axis_aligned_bounding_box(),#                                    #o3d.geometry.TriangleMesh.create_coordinate_frame(size=20)#                                    ])#虽然这种方法可以保存视角,但是无法与hidden_point_removal联合使用#save_view_point(model_point, "viewpoint.json")#load_view_point(model_point, "viewpoint.json")#如果想要螺柱在螺母中不显示,需要用到视角遮挡消除,但是视角计算的时候使用的是计算出来的视角'''|  hidden_point_removal(...)|      hidden_point_removal(self, camera_location, radius)|      |      Removes hidden points from a point cloud and returns a mesh of the remaining points. Based on Katz et al. 'Direct Visibility of Point Sets', 2007.|      |      Args:|          camera_location (numpy.ndarray[float64[3, 1]]): All points not visible from that location will be reomved|          radius (float): The radius of the sperical projection|      |      Returns:|          Tuple[open3d.geometry.TriangleMesh, List[int]]'''diameter = np.linalg.norm(np.asarray(model_point.get_max_bound()) - np.asarray(model_point.get_min_bound()))#camera = [0, 0, diameter]camera = [ diameter/2, diameter/2, diameter]#camera = [0, 0, 44]radius = diameter*100print("Get all points that are visible from given view point")_, pt_map = model_point.hidden_point_removal(camera, radius)#https://github.com/intel-isl/Open3D/issues/1860#open3d-0.9.0#select_point = model_point.select_by_index(pt_map)select_point = model_point.select_down_sample(pt_map)o3d.visualization.draw_geometries([select_point,o3d.geometry.TriangleMesh.create_coordinate_frame(size=50),o3d.geometry.TriangleMesh.create_coordinate_frame(size=20, origin=camera),select_point.get_axis_aligned_bounding_box(),])#通过颜色确定label,保存为pcdlabel = model_point.colorsnp_label = np.asarray(label).astype(np.int)points = model_point.pointsnp_points = np.asarray(points)ind_washer = np.intersect1d(np.where(np_label[:,0] == 1), np.where(np_label[:,1] == 0), np.where(np_label[:,2] == 0))ind_stud = np.intersect1d(np.where(np_label[:,0] == 0), np.where(np_label[:,1] == 1), np.where(np_label[:,2] == 0))ind_plane = np.intersect1d(np.where(np_label[:,0] == 0), np.where(np_label[:,1] == 0), np.where(np_label[:,2] == 1))ind_nut = np.intersect1d(np.where(np_label[:,0] == 1), np.where(np_label[:,1] == 1), np.where(np_label[:,2] == 0))np_washer = np_points[ind_washer][:, :3]np_stud = np_points[ind_stud][:, :3]np_plane = np_points[ind_plane][:, :3]np_nut = np_points[ind_nut][:, :3]t_lab = np.ones((np_washer.shape[0], 1), dtype=np.int8) * 0p_washer = np.hstack((np_washer, t_lab))t_lab = np.ones((np_stud.shape[0], 1), dtype=np.int8) * 1p_stud = np.hstack((np_stud, t_lab))t_lab = np.ones((np_plane.shape[0], 1), dtype=np.int8) * 2p_plane = np.hstack((np_plane, t_lab))t_lab = np.ones((np_nut.shape[0], 1), dtype=np.int8) * 3p_nut = np.hstack((np_nut, t_lab))write_pcd_fun1(np.vstack((p_washer, p_stud, p_plane, p_nut)), ply_path.replace('.ply', '.pcd'))if __name__ == "__main__":parser = argparse.ArgumentParser(description="creat bolt")parser.add_argument('-if',"--input_scad",default='./hex_head2.scad',help="set input scad file")parser.add_argument('-os',"--output_stl_folder",default='./result_stl/',help="set output stl folder")parser.add_argument('-op',"--output_ply_folder",default='./result_ply/',help="set output ply folder")args = parser.parse_args()if args.input_scad is None:parser.print_help()exit()main(args)'''
https://openscad.org/
https://github.com/nickc92/ViewSCAD
https://github.com/SolidCode/SolidPython
https://github.com/cnr-isti-vclab/PyMeshLabpython -mpip install open3d==0.9.0
sudo apt-get install openscad (2015.03-1+dfsg-3)
solid                  0.2.0
solidpython            0.4.2
python -mpip install solid==0.2.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
python -mpip install solidpython==0.4.2 -i https://pypi.tuna.tsinghua.edu.cn/simplejupyter可视化
python -mpip install viewscad==0.2.0
安装插件:
jupyter labextension install @jupyter-widgets/jupyterlab-manager
https://pypi.org/project/jupyter-openscad-kernel/https://pymeshlab.readthedocs.io/en/latest/
python -mpip install pymeshlab==0.2
'''

右手坐标系统,X = Red, Y = Green, Z = Blue

demo_bolt_004.py

# python3.8
# -*- coding: utf-8 -*-
# ---
# @Software: PyCharm
# @File: demo_bolt_002.py
# @Author: ---
# @Institution: BeiJing, China
# @E-mail: lgdyangninghua@163.com
# @Site:
# @Time: 5月 12, 2021
# ---
import argparse
from solid import *
from solid.utils import *
import viewscad
import open3d as o3d
import os
import pathlib
import copy
import numpy as npHEADER = '''\
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z label
SIZE 4 4 4 4
TYPE F F F I
COUNT 1 1 1 1
WIDTH {}
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS {}
DATA ascii
'''
def write_pcd_fun1(points, save_pcd_path):n = len(points)lines = []for i in range(n):x, y, z, label = points[i]lines.append('{:.6f} {:.6f} {:.6f} {}'.format(x, y, z, label))with open(save_pcd_path, 'w') as f:f.write(HEADER.format(n, n))f.write('\n'.join(lines))
def write_pcd_fun2(points, save_pcd_path):with open(save_pcd_path, 'w') as f:f.write(HEADER.format(len(points), len(points)) + '\n')np.savetxt(f, points, delimiter=' ', fmt='%f %f %f %d')#https://blog.csdn.net/weixin_48994268/article/details/115682269
#open3d连续读取pcd文件及实现点云视角转换
def save_view_point(pcd, filename):vis = o3d.visualization.Visualizer()vis.create_window(window_name='pcd', width=800, height=600)vis.add_geometry(pcd)vis.run()  # user changes the view and press "q" to terminateparam = vis.get_view_control().convert_to_pinhole_camera_parameters()o3d.io.write_pinhole_camera_parameters(filename, param)vis.destroy_window()
def load_view_point(pcd, filename):vis = o3d.visualization.Visualizer()vis.create_window(window_name='pcd', width=800, height=600)ctr = vis.get_view_control()param = o3d.io.read_pinhole_camera_parameters(filename)vis.add_geometry(pcd)ctr.convert_from_pinhole_camera_parameters(param)vis.run()vis.destroy_window()scad_parameter={#平面距离坐标原点的高度'tran_init': 0,#底平面参数'plate_side': 70,'plate_height': 1,#垫片参数'washer_out_diam': 50,'washer_in_diam': 0,'washer_height': 2,#螺母参数'bolt_height': 22, #大小-高度'bolt_diam': 35, #大小-宽度'bolt_tran': 15, #上下-高度'bolt_rot': 15, #角度#螺柱参数'screw_diam': 16,'screw_height': 44,
}label_dict = {"other": 0, #washer"stud": 1,"plane": 2,"nut": 3,
}def mkdir_os(path):if not os.path.exists(path):os.makedirs(path)def main(args):scad_path = pathlib.Path(args.input_scad)if not scad_path.is_file():print("input_scad error")returnmkdir_os(args.output_stl_folder)mkdir_os(args.output_ply_folder)scad_F = import_scad(args.input_scad)index = 0count = scad_parameter['screw_height'] * (180/10)for nut_height in range(0, scad_parameter['screw_height'], 2):for nut_angle in range(0, 180, 75):index += 1print(index, "/", count)save_stl_name = "bolt1_index{:0>5d}_nut_height-{}_nut_angle-{}.stl".format(index, nut_height, nut_angle)stl_path = os.path.join(args.output_stl_folder, save_stl_name)scad_model = scad_F.hex_head2(tran_init=scad_parameter['tran_init'],plate_side=scad_parameter['plate_side'],plate_height=scad_parameter['plate_height'],washer_out_diam=scad_parameter['washer_out_diam'],washer_in_diam=scad_parameter['washer_in_diam'],washer_height=scad_parameter['washer_height'],bolt_height=scad_parameter['bolt_height'],bolt_diam=scad_parameter['bolt_diam'],bolt_tran=nut_height,bolt_rot=nut_angle,screw_diam=scad_parameter['screw_diam'],screw_height=scad_parameter['screw_height'])#分开生成形成label#垫圈+otherwasher = copy.deepcopy(scad_model)washer.params["plate_height"] = 0washer.params["bolt_height"] = 0washer.params["screw_height"] = 0#螺柱stud = copy.deepcopy(scad_model)stud.params["plate_height"] = 0stud.params["washer_height"] = 0stud.params["bolt_height"] = 0#底平面plane = copy.deepcopy(scad_model)plane.params["washer_height"] = 0plane.params["bolt_height"] = 0plane.params["screw_height"] = 0#螺母nut = copy.deepcopy(scad_model)nut.params["plate_height"] = 0nut.params["washer_height"] = 0nut.params["screw_height"] = 0model_list = [washer, stud, plane, nut]mesh_list = []color_list = [[1, 0, 0],[0, 1, 0],[0, 0, 1],[1, 1, 0]]for ind, mod in enumerate(model_list):v_rander = viewscad.Renderer()v_rander.render(mod, outfile=stl_path) #这里已经保存了stl,但是是ascii format#pymeshlabimport pymeshlab as mlms = ml.MeshSet()ms.load_new_mesh(stl_path)filename_mesh_out = os.path.join(args.output_stl_folder, "pymeshlab_"+save_stl_name)ms.save_current_mesh(filename_mesh_out)#这里之所以使用pymeshlab保存的stl,是因为open3d0.9.0有点问题,只能打开二进制的stl#https://github.com/intel-isl/Open3D/issues/2479#open3dmesh_bolt = o3d.io.read_triangle_mesh(filename_mesh_out)mesh_bolt.paint_uniform_color(color_list[ind])mesh_list.append(mesh_bolt)model = mesh_list[0] + mesh_list[1] + mesh_list[2] + mesh_list[3]model_point = model.sample_points_poisson_disk(number_of_points=15000)print('model_point:', model_point)model_point = model_point.voxel_down_sample(voxel_size=1)print('model_point', model_point)radius = 11000camera3 = [60, 100]for cam_z, cameraZ in enumerate(camera3):save_ply_name = "bolt1_index{:0>5d}_nut_height-{}_nut_angle-{}_camZ-{}.ply".format(index, nut_height, nut_angle, cameraZ)ply_path = os.path.join(args.output_ply_folder, save_ply_name)# o3d.visualization.draw_geometries([model_point,#                                    o3d.geometry.TriangleMesh.create_coordinate_frame(size=50),#                                    model_point.get_axis_aligned_bounding_box(),#                                    ])camera = [70, 70, cameraZ]_, pt_map = model_point.hidden_point_removal(camera, radius)select_point = model_point.select_down_sample(pt_map)# o3d.visualization.draw_geometries([select_point,#                                    o3d.geometry.TriangleMesh.create_coordinate_frame(size=50),#                                    select_point.get_axis_aligned_bounding_box(),#                                    ])#通过颜色确定label,保存为pcdlabel = select_point.colorsnp_label = np.asarray(label)#不要使用取整,会发生[1 1 0]变成[0 0 0]的情况,具体我还不知道为什么#np_label = np_label.astype(np.int)#np_label = np.floor(np_label)points = select_point.pointsnp_points = np.asarray(points)ind_washer = np.intersect1d(np.where(np_label[:,0] >= 0.5), np.where(np_label[:,1] == 0), np.where(np_label[:,2] == 0))ind_stud = np.intersect1d(np.where(np_label[:,0] == 0), np.where(np_label[:,1] >= 0.5), np.where(np_label[:,2] == 0))ind_plane = np.intersect1d(np.where(np_label[:,0] == 0), np.where(np_label[:,1] == 0), np.where(np_label[:,2] >= 0.5))ind_nut = np.intersect1d(np.where(np_label[:,0] >= 0.5), np.where(np_label[:,1] >= 0.5), np.where(np_label[:,2] == 0))np_washer = np_points[ind_washer][:, :3]np_stud = np_points[ind_stud][:, :3]np_plane = np_points[ind_plane][:, :3]np_nut = np_points[ind_nut][:, :3]# pcd1 = o3d.geometry.PointCloud()# pcd1.points = o3d.utility.Vector3dVector(np_washer)# pcd1.paint_uniform_color(color_list[0])# pcd2= o3d.geometry.PointCloud()# pcd2.points = o3d.utility.Vector3dVector(np_stud)# pcd2.paint_uniform_color(color_list[1])# pcd3 = o3d.geometry.PointCloud()# pcd3.points = o3d.utility.Vector3dVector(np_plane)# pcd3.paint_uniform_color(color_list[2])# pcd4 = o3d.geometry.PointCloud()# pcd4.points = o3d.utility.Vector3dVector(np_nut)# pcd4.paint_uniform_color(color_list[3])# o3d.visualization.draw_geometries([pcd1,pcd2,pcd3,pcd4,#                                    o3d.geometry.TriangleMesh.create_coordinate_frame(size=50),#                                    select_point.get_axis_aligned_bounding_box(),#                                    ])t_lab = np.ones((np_washer.shape[0], 1), dtype=np.int8) * 0p_washer = np.hstack((np_washer, t_lab))t_lab = np.ones((np_stud.shape[0], 1), dtype=np.int8) * 1p_stud = np.hstack((np_stud, t_lab))t_lab = np.ones((np_plane.shape[0], 1), dtype=np.int8) * 2p_plane = np.hstack((np_plane, t_lab))t_lab = np.ones((np_nut.shape[0], 1), dtype=np.int8) * 3p_nut = np.hstack((np_nut, t_lab))write_pcd_fun1(np.vstack((p_washer, p_stud, p_plane, p_nut)), ply_path.replace('.ply', '.pcd'))if __name__ == "__main__":parser = argparse.ArgumentParser(description="creat bolt")parser.add_argument('-if',"--input_scad",default='./hex_head2.scad',help="set input scad file")parser.add_argument('-os',"--output_stl_folder",default='./result_stl/',help="set output stl folder")parser.add_argument('-op',"--output_ply_folder",default='./result_ply/',help="set output ply folder")args = parser.parse_args()if args.input_scad is None:parser.print_help()exit()main(args)'''
https://openscad.org/
https://github.com/nickc92/ViewSCAD
https://github.com/SolidCode/SolidPython
https://github.com/cnr-isti-vclab/PyMeshLabpython -mpip install open3d==0.9.0
sudo apt-get install openscad (2015.03-1+dfsg-3)
solid                  0.2.0
solidpython            0.4.2
python -mpip install solid==0.2.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
python -mpip install solidpython==0.4.2 -i https://pypi.tuna.tsinghua.edu.cn/simplejupyter可视化
python -mpip install viewscad==0.2.0
安装插件:
jupyter labextension install @jupyter-widgets/jupyterlab-manager
https://pypi.org/project/jupyter-openscad-kernel/https://pymeshlab.readthedocs.io/en/latest/
python -mpip install pymeshlab==0.2
'''

生成shapenet格式

# python3.8
# -*- coding: utf-8 -*-
# ---
# @Software: PyCharm
# @File: creat_train_txt.py.py
# @Author: ---
# @Institution: BeiJing, China
# @E-mail: lgdyangninghua@163.com
# @Site:
# @Time: 5月 24, 2021
# ---
import os
import cv2
import open3d as o3d
import numpy as np
import jsondef mkdir_os(path):if not os.path.exists(path):os.makedirs(path)def get_plane(cloud, distance_threshold=0.01, ransac_n=10, num_iterations=200, rt_plane=False):coefficients, inliers = cloud.segment_plane(distance_threshold=distance_threshold,ransac_n=ransac_n,num_iterations=num_iterations)if rt_plane:mmin = np.min(pcd2npy(cloud), axis=0).reshape(-1, 1)mmax = np.max(pcd2npy(cloud), axis=0).reshape(-1, 1)bbox = np.concatenate([mmin, mmax], axis=1)x_range, y_range = bbox[0, :], bbox[1, :]cloud_plane = generate_plane_points(coefficients, x_range, y_range)return coefficients, cloud_planereturn coefficientsdef points_plane_dists(points, coef):ones = np.ones(shape=(len(points), 1)).astype(np.float32)points = np.concatenate([points, ones], axis=1)coef = np.array(coef).reshape(4, 1)dists = np.squeeze(np.matmul(points, coef))return distscategory = "luomu_openscad"
save_path = "shapenet"mkdir_os(save_path)
mkdir_os(os.path.join(save_path, "train_test_split"))
mkdir_os(os.path.join(save_path, category))data_path = "./result_ply"
lines = os.listdir(data_path)'''
luomu模型:
label_dict = {"other": 0, 背景(垫圈噪声等属于背景类)"stud": 1, 螺柱(螺母上部分的螺栓点云才是我们的感兴趣点云)"plane": 2, 平面"nut": 3, 螺母
}luoshuan模型:
label_dict = {"other": 0, 背景(垫圈噪声等属于背景类)"bolt": 1, 螺栓"plane": 2, 平面
}
'''train_list, test_list, val_list = [], [], []
for ind, line in enumerate(lines):print(ind, "/", len(lines))pcd = os.path.join(data_path, line)with open(pcd, "r") as f:data = f.readlines()data_point3d = data[11:]#该数据存在问题,我想要的是螺母之上的螺栓为label==1,螺母之下的label==0(背景类),若螺母拧过螺柱,那么此时没有点云label==1other_list = []stud_list = []plane_list = []nut_list = []all_list = []for m_line in data_point3d:temp = m_line.split(" ")label = int(float(temp[3].strip()))if label == 0:other_list.append([float(temp[0]), float(temp[1]), float(temp[2]), label])all_list.append([float(temp[0]), float(temp[1]), float(temp[2]), label])elif label == 1:stud_list.append([float(temp[0]), float(temp[1]), float(temp[2]), label])elif label == 2:plane_list.append([float(temp[0]), float(temp[1]), float(temp[2]), label])all_list.append([float(temp[0]), float(temp[1]), float(temp[2]), label])elif label == 3:nut_list.append([float(temp[0]), float(temp[1]), float(temp[2]), label])all_list.append([float(temp[0]), float(temp[1]), float(temp[2]), label])else:exit()color_list = [[1, 0, 0],[0, 1, 0],[0, 0, 1],[1, 1, 0]]np_data = np.array(all_list)other_o3d = o3d.geometry.PointCloud()other_o3d.points = o3d.utility.Vector3dVector(np.array(other_list)[:, 0:3])other_o3d.paint_uniform_color(color_list[0])stud_o3d= o3d.geometry.PointCloud()stud_o3d.points = o3d.utility.Vector3dVector(np.array(stud_list)[:, 0:3])stud_o3d.paint_uniform_color(color_list[1])plane_o3d = o3d.geometry.PointCloud()plane_o3d.points = o3d.utility.Vector3dVector(np.array(plane_list)[:, 0:3])plane_o3d.paint_uniform_color(color_list[2])nut_o3d = o3d.geometry.PointCloud()nut_o3d.points = o3d.utility.Vector3dVector(np.array(nut_list)[:, 0:3])nut_o3d.paint_uniform_color(color_list[3])# o3d.visualization.draw_geometries([other_o3d,stud_o3d,plane_o3d,nut_o3d,#                                    o3d.geometry.TriangleMesh.create_coordinate_frame(size=50),#                                    #select_point.get_axis_aligned_bounding_box(),#                                    ])coefficients = get_plane(plane_o3d)d_list = []a, b, c = coefficients[0], coefficients[1], coefficients[2]for index, pt in enumerate(np.array(nut_list)[:, 0:3]):x, y, z = ptif x != 0 and y != 0 and z != 0:d = (0 - (a * x + b * y + c * z))d_list.append(d)d_list = np.sort(np.array(d_list), axis=0)d_parameter = np.mean(d_list[5:10], axis=0, dtype=np.float32)coefficients[3] = d_parameterpp_dists = points_plane_dists(np.array(stud_list)[:, 0:3], coefficients)ind_below = np.where(pp_dists<0)ind_above = np.where(pp_dists>=0)points_below = np.array(stud_list)[ind_below]points_below[:, 3] = 0points_above = np.array(stud_list)[ind_above]if points_below.size != 0:data_point3d = np.vstack((np_data, points_below))if points_above.size != 0:data_point3d = np.vstack((np_data, points_above))with open(os.path.join(save_path, category, line.replace('.pcd', '.txt')), "w") as f:for m_val in data_point3d:f.write("{} {} {} 0.0 0.0 0.0 {}\n".format(m_val[0], m_val[1], m_val[2], m_val[3]))train_list.append(os.path.join(save_path, category, line.split(".pcd")[0]))with open(os.path.join(save_path, "synsetoffset2category.txt"), "w") as f:f.write("luomu\tluomu_openscad\n")with open(os.path.join(save_path, "train_test_split", "shuffled_test_file_list.json"), "w") as f_obj:json.dump(train_list, f_obj, indent=1)
with open(os.path.join(save_path, "train_test_split", "shuffled_train_file_list.json"), "w") as f_obj:json.dump(train_list, f_obj, indent=1)
with open(os.path.join(save_path, "train_test_split", "shuffled_val_file_list.json"), "w") as f_obj:json.dump(train_list, f_obj, indent=1)

openscad螺栓数据生成相关推荐

  1. openscad螺栓数据生成2

    下载库: BOSL2 https://github.com/revarbat/BOSL2 ubuntu16.04  openscad2021版本 放入:/home/×××/.local/share/O ...

  2. 谷歌BERT预训练源码解析(一):训练数据生成

    目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...

  3. autoware使用rosbag数据生成路径点并进行路径规划(七)

    autoware使用rosbag数据生成路径点并进行路径规划(七) 第一步启动autoware和播放数据包 $ cd ~/autoware.ai $ source install/setup.bash ...

  4. Web 开发人员必备的随机 JSON 数据生成工具

    在 Web 开发中,经常会需要一些测试数据来测试接口或者功能时候正确.JSON Generator 就是这样一款生成随机 JSON 数据的在线工具,Web 开发人员必备,记得收藏和分享啊. 您可能感兴 ...

  5. oracle 查询本周数据生成下周数据

    CreateTime--2018年1月4日16:38:01 Author:Marydon oracle 查询本周数据生成下周数据 第一步:查询指定区间数据 第二步:改变查询结果的值 查询日期字段+7 ...

  6. pandas编写自定义函数、使用apply函数应用自定义函数基于Series数据生成新的dataframe

    pandas编写自定义函数.使用apply函数应用自定义函数基于Series数据生成新的dataframe 目录 pandas编写自定义函数.使用apply函

  7. pandas使用replace函数移除dataframe数值数据中的逗号并基于处理后的数据生成新的整型数据列(remove comma from column values in Pandas)

    pandas使用replace函数移除dataframe数值数据中的逗号并基于处理后的数据生成新的整型数据列(remove comma from column values in Pandas Dat ...

  8. R语言使用edit函数在Rsudio中生成数据编辑器(在windows中生成编辑器)、在编辑器中输出需要的数据生成最终的dataframe

    R语言使用edit函数在Rsudio中生成数据编辑器(在windows中生成编辑器).在编辑器中输出需要的数据生成最终的dataframe 目录

  9. 将表数据生成Insert脚本

    -- ============================================= -- Author: 明永成 -- Create date: 2016-01-03 -- Descri ...

最新文章

  1. java 常见数据类型
  2. Vs 控件错位 右侧资源管理器文件夹点击也不管用,显示异常
  3. Spring Boot中登录错误消息的显示
  4. python qt库,用于 Python 的高级 GUI 库(Qt 和 PyQt)(1)Unix系统 -电脑资料
  5. 力扣题目——637. 二叉树的层平均值
  6. [NOIP2015]金币
  7. tensorflow错误:InvalidArgumentError (see above for traceback): Cannot assign a device for operation
  8. 安装布署rsync+Inotify实现数据的实时同步更新
  9. 隔壁小孩也能看懂的面向对象(概念篇)
  10. .net 获取邮箱邮件列表和内容
  11. java 微信文章评论点赞_微信文章评论点赞刷赞工具及微信文章评论点赞软件使用教程...
  12. 一个方便快捷gif在线水印制作(支持文字和图片)
  13. 农产品管理系统-毕设
  14. 2021.09青少年软件编程(Python)等级考试试卷(五级)
  15. linux服务器系统时间和bios时间,Linux系统时间, 硬件BIOS时间的校准与同步
  16. Linux嵌入式开发 -- imx6ull 主频配置
  17. 银行职业性格测试软件,2018银行春招:不要小看银行性格测试
  18. jav常用类-时间处理相关类
  19. C++实现与电脑进行石头剪刀布的游戏
  20. 疾病研究:DMD及BMD的机理和临床表现(译稿)

热门文章

  1. Linux文件系统保护最佳实践:Tripwire
  2. SPSS 主成分分析(Principal Component Analysis,PCA)
  3. 用 Python 把你的朋友变成表情包
  4. 仿天猫 购物车(Android studio 仿天猫 详情页面 添加购物车选择 颜色 尺寸demo)
  5. linux的tar命令之-N参数详解
  6. iOS11正式版亮点
  7. 蓝桥杯单片机数码管动态显示_关于蓝桥杯训练小程序 中断控制数码管显示数字的左右移动...
  8. python中计时方法
  9. pixabay注册失败原因以及解决办法
  10. URL中文转义和特殊字符处理