Simple yet powerful CAD (Computer Aided Design) library, written with Python.

Overview

madcad-logo

Py-MADCAD

>>> it's time to throw parametric softwares out !

Simple yet powerful CAD (Computer Aided Design) library, written with Python.

support-version PyPI version shields.io Documentation Status

Features

  • surface generation (3D sketch primitives, extrusion, revolution, inflation, tubes, ...)
  • fast boolean operations
  • common mesh file format import/export
  • kinematic manipulation
  • implicit geometry definition through the constraint/solver system
  • objects display with high-quality graphics

example-bearing

Checkout some complete examples

Sample usage

from madcad import *

# define points
O = vec3(0)
A = vec3(2,0,0)
B = vec3(1,2,0)
C = vec3(0,2,0)

# create a list of primitives
line = [
	Segment(O, A),          
	ArcThrough(A, B, C),
	Segment(C,O),           
	]

# create and solve constraints
solve([
		Tangent(line[0], line[1], A),   
		Tangent(line[1], line[2], C),   
		Radius(line[1], 1.5),           
	], fixed=[O])

# generate surfaces
part = extrusion(vec3(0,0,1), web(line))

# display in a 3D scene
show([part])

The result will be this window example-window

About

MADCAD is born from the idea that the current approach of parametric CADs for mechanical engineering is not the best possible. This library is part of a project targeting the best possible mechanical design tool for both engineers and handymen. See the comparison for more details.

License LGPL logo

Copyright 2019-2021 Yves Dejonghe [email protected]

This library is distributed under the LGPL-v3 license. A copy of that license is provided with this software.

Comments
  • Error while using pip install pymadcad

    Error while using pip install pymadcad

    Hello Thanks for the great work. I tried to install pymadcad using pip install pymadcad but unfortunately I faced the following error:

    Running setup.py install for pymadcad ... error
        ERROR: Command errored out with exit status 1:
         command: 'c:\users\faez\pycharmprojects\pyshop\venv\scripts\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Use
    rs\\Faez\\AppData\\Local\\Temp\\pip-install-ul46jryj\\pymadcad_caf2118f1998466b8c8789fadbc9af8c\\setup.py'"'"'; __file__='"'"'C:\\Users\\Faez\\AppData\\
    Local\\Temp\\pip-install-ul46jryj\\pymadcad_caf2118f1998466b8c8789fadbc9af8c\\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.
    path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();
    exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\Faez\AppData\Local\Temp\pip-record-fkz6pgb4\install-record.txt' --single-versi
    on-externally-managed --compile --install-headers 'c:\users\faez\pycharmprojects\pyshop\venv\include\site\python3.8\pymadcad'
             cwd: C:\Users\Faez\AppData\Local\Temp\pip-install-ul46jryj\pymadcad_caf2118f1998466b8c8789fadbc9af8c\
        Complete output (77 lines):
        running install
        running build
        running build_py
        creating build
        creating build\lib.win-amd64-3.8
        creating build\lib.win-amd64-3.8\madcad
        copying madcad\asso.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\blending.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\boolean.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\common.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\constraints.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\cut.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\displays.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\gear.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\generation.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\hashing.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\io.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\joints.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\kinematic.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\mathutils.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\mesh.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\nprint.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\primitives.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\rendering.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\reverse.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\scheme.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\selection.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\settings.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\text.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\triangulation.py -> build\lib.win-amd64-3.8\madcad
        copying madcad\__init__.py -> build\lib.win-amd64-3.8\madcad
        creating build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\annotation.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\axis.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\font.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\ghost.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\glowenvelope.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\ident.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\pointhalo.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\scheme-ghost.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\scheme-ident.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\scheme-uniform.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\simple-solid.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\solid-old.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\solid.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\uniformcolor.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\viewgrid.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\wire.frag -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\annotation.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\axis-ident.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\axis.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\font.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\glowenvelope.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\object-ident.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\object-item-ident.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\pointhalo-ident.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\pointhalo.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\scheme.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\solid.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\uniformcolor.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\viewgrid.vert -> build\lib.win-amd64-3.8\madcad\shaders
        copying madcad\shaders\wire.vert -> build\lib.win-amd64-3.8\madcad\shaders
        creating build\lib.win-amd64-3.8\madcad\textures
        copying madcad\textures\point.png -> build\lib.win-amd64-3.8\madcad\textures
        copying madcad\textures\skybox-blue-dense.png -> build\lib.win-amd64-3.8\madcad\textures
        copying madcad\textures\skybox-blue.png -> build\lib.win-amd64-3.8\madcad\textures
        copying madcad\textures\skybox-test.png -> build\lib.win-amd64-3.8\madcad\textures
        copying madcad\textures\skybox-violet-dense.png -> build\lib.win-amd64-3.8\madcad\textures
        copying madcad\textures\skybox-violet-saturated.png -> build\lib.win-amd64-3.8\madcad\textures
        copying madcad\textures\skybox-violet.png -> build\lib.win-amd64-3.8\madcad\textures
        copying madcad\textures\skybox-white.png -> build\lib.win-amd64-3.8\madcad\textures
        copying madcad\textures\skybox.png -> build\lib.win-amd64-3.8\madcad\textures
        copying madcad\core.pyx -> build\lib.win-amd64-3.8\madcad
        copying madcad\core.c -> build\lib.win-amd64-3.8\madcad
        running build_ext
        building 'madcad.core' extension
        error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-buil
    d-tools/
        ----------------------------------------
    ERROR: Command errored out with exit status 1: 'c:\users\faez\pycharmprojects\pyshop\venv\scripts\python.exe' -u -c 'import io, os, sys, setuptools, tok
    enize; sys.argv[0] = '"'"'C:\\Users\\Faez\\AppData\\Local\\Temp\\pip-install-ul46jryj\\pymadcad_caf2118f1998466b8c8789fadbc9af8c\\setup.py'"'"'; __file_
    _='"'"'C:\\Users\\Faez\\AppData\\Local\\Temp\\pip-install-ul46jryj\\pymadcad_caf2118f1998466b8c8789fadbc9af8c\\setup.py'"'"';f = getattr(tokenize, '"'"'
    open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r
    \n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\Faez\AppData\Local\Temp\pip-record-fkz6pgb4\i
    nstall-record.txt' --single-version-externally-managed --compile --install-headers 'c:\users\faez\pycharmprojects\pyshop\venv\include\site\python3.8\pym
    adcad' Check the logs for full command output.
    

    How can I resolve this issue. Thank you so much

    opened by FaezAlkadi 16
  • ImportError on windows due to `os.getenv('HOME')`

    ImportError on windows due to `os.getenv('HOME')`

    I have installed the module on my pc (Windows 10 x64 - Python 3.10) and I tried to run the Sample that I found on the main page of the GitHub repository, but when I tray to run it I get this error:

    unsupported operand type(s) for +: 'NoneType' and 'str'

    What could it be?

    opened by XBlayz 7
  • Triangulation Error on madcad.union()

    Triangulation Error on madcad.union()

    Hello to Jimy and the community, thank you for the hard work !

    For a project, we need to compute the union of n Meshes. The user can select 2 meshes or more and we need to "merge" them in only one Mesh. These meshes are imported via an STL file. We use madcad.read() to import them in the scene :

    def load_stl(self, filename):
            _mesh_stl = madcad.read(filename)
            _mesh_stl.mergeclose()
    [...]
    

    We are then using the function madcad.union() to achieve this fusion, in this way :

    def merge_meshes(a_key, b_key):
            self.shapes3d[a_key].finish()
            self.shapes3d[b_key].finish()
            _union = madcad.union(
                self.shapes3d[a_key],
                self.shapes3d[b_key])
            _union.finish()
    

    In some cases, it does work pretty well : when the shapes are simple especially. It is, for example, easy to compute these unions of meshes to achieve this "complex" mesh : image For this mesh, we used a tube and a sphere.

    But now let's use a slightly more complex shape to replace the sphere. image When trying to compute the fusion with a tube... (Moving the new shape to have an intersection, unless it simply doesn't work) image We get an error :

    Traceback (most recent call last):
      File "c:\Users\yarkane\source\repos\project\model\view_3d.py", line 324, in merge_list_meshes
        _union_key = self.merge_meshes(_union_key, _key_b, keep_other_items)
      File "c:\Users\yarkane\source\repos\project\model\view_3d.py", line 294, in merge_meshes
        _union = madcad.union(
      File "C:\Users\yarkane\source\repos\project\lib\site-packages\madcad\boolean.py", line 608, in union
        return boolean(a,b, (False,False))
      File "C:\Users\yarkane\source\repos\project\lib\site-packages\madcad\boolean.py", line 602, in boolean
        return op(a, b, sides, prec)
      File "C:\Users\yarkane\source\repos\project\lib\site-packages\madcad\boolean.py", line 248, in boolean_mesh
        mc2 = pierce_mesh(m2, m1, selector[1], prec)
      File "C:\Users\yarkane\source\repos\project\lib\site-packages\madcad\boolean.py", line 164, in pierce_mesh
        m1, frontier = cut_mesh(m1, m2, prec)
      File "C:\Users\yarkane\source\repos\project\lib\site-packages\madcad\boolean.py", line 145, in cut_mesh
        flat = triangulation.triangulation_closest(segts, normal)
      File "C:\Users\yarkane\source\repos\project\lib\site-packages\madcad\triangulation.py", line 814, in triangulation_closest
        result += triangulation_outline(loop, z)
      File "C:\Users\yarkane\source\repos\project\lib\site-packages\madcad\triangulation.py", line 289, in triangulation_outline
        raise TriangulationError("no more feasible triangles (algorithm failure or bad input outline)", [outline.indices[i] for i in hole])
    madcad.triangulation.TriangulationError: ('no more feasible triangles (algorithm failure or bad input outline)', [109, 87, 100])
    

    I guess this is because boolean operations are very sensible, and the meshes too complex. Is there at least a way to "simplify" the mesh ? For example, we also got TriangulationErrors when trying to extrude from polygons that were quite "complex", and we managed to fix the issue by calling an opencv function to "smooth" the polygon. Maybe there is a way for this 3D operation to smooth the meshes ?

    Anyway, we will continue to dig on this topic. Thanks for the hard work and all the help you could give ! :)

    opened by Yarkane 6
  • thicken does not work on directly imported STL

    thicken does not work on directly imported STL

    from madcad import * from madcad.io import * from madcad.generation import * print("runing here ") surface=read("data/aa.stl") print("runing here 0") surface = thicken(surface,0.1 ,0.5) print("runing here 1") write(surface, 'data/A12.stl') print("runing here 2") show([surface])

    python thickentest.py runing here runing here 0

    that mean I can't run thicken(surface,0.1 ,0.5) . the STL file is fine. I can open it on other software

    invalid 
    opened by donaldlee2008 5
  • Create a new mesh

    Create a new mesh

    Your work is quite useful and convenient for my research. But I have a trouble now, because of some unknown problem I can only install v0.10.2 at most. If I have a set of n*3 numpy arrays, how can I easily convert them to the format required by faces so that I can construct a mesh by myself?

    opened by Eva-xx 4
  • Boolean Operations Through Meshes

    Boolean Operations Through Meshes

    Hi, I've been trying to compute boolean operations between two meshes, one of which has been imported from outside and read by "madcad.read" command and the other one generated through the "madcad.brick" , but I got this type of error: "Process finished with exit code -1073741819 (0xC0000005)".
    Does anyone have any suggestions on how to cope with this problem? Thanks a lot in advance

    invalid 
    opened by charlotte10170 4
  • Problems with using booleans(Intersection)

    Problems with using booleans(Intersection)

    Hi,

    I just installed pymadcad and going my first steps and I cant figure out how the boolean functions are supposed to work. The closest I have come to my expected result was with the following code:

      m1 = madcad.brick(width=madcad.vec3(2))
      m2 = m1.transform(madcad.vec3(1, -0.5, 1))
      print(m1)
      print(m2)
      m3 = madcad.boolean.intersectwith(m1, m2)
      print(madcad.Mesh(m3))
    

    Am I using it wrong?

    the corresponding output was the following:

    Mesh(
      points= [dvec3(            1,           -1,           -1 ),
                          ...
               dvec3(           -1,            1,           -1 )],
      faces=  [(0, 1, 2),
               ...,
               (4, 0, 3),
               (4, 3, 7)],
      tracks= [0,
               0,
               1,
                 ...
               5,
               5],
      groups= [None,
               None,
               None,
               None,
               None,
               None],
      options= {})
    Mesh(
      points= [dvec3(            2,         -1.5,            0 ),
               dvec3(            2,         -1.5,            2 ),
               dvec3(            0,         -1.5,            2 ),
               dvec3(            0,         -1.5,            0 ),
               dvec3(            2,          0.5,            0 ),
               dvec3(            2,          0.5,            2 ),
               dvec3(            0,          0.5,            2 ),
               dvec3(            0,          0.5,            0 )],
      faces=  [(0, 1, 2),
               (0, 2, 3),
               ...
               (4, 3, 7)],
      tracks= [0,
               0,
               1,
               ...
               5,
               5],
      groups= [None,
               None,
               None,
               None,
               None,
               None],
      options= {})
    Mesh(
      points= [((8, 9), 9),
               ((10, 9), 10),
               ((15, 13), 2),
               ((10, 13), 10),
               ((15, 17), 2),
               ((8, 17), 8)],
      faces=  [],
      tracks= [],
      groups= [],
      options= {})
    

    Thanks a lot for in advance and for doing this project in general. It sounds really promising

    Lukas

    bug 
    opened by hit-the-luke 4
  • missing .gitignore,

    missing .gitignore,

    Hi,

    As developer and someone who wants to contribute to this project I am missing a ".gitignore" file.

    Without the .gitignore file i do not know which files should be excluded included in future pull requests.

    opened by GlennWSo 3
  • Function

    Function "blendpair" in "blending.py" issues

    Hello, I was trying some functions to make a part.

    madcad version 0.7

    Here is my code:

    from madcad import *
    
    circle1 = Circle((vec3(0,0,0),vec3(0,0,1)),5)
    circle2 = Circle((vec3(0,0,0),vec3(0,0,1)),20)
    z = blendpair(circle1, circle2, tangents = "straight")
    z = extrusion(vec3(0,0,10), z)
    show([z])
    

    The following image is the result: example

    The hole is not empty and there are some strange lines near the central circle as you can see. Maybe is my code wrong ?

    bug 
    opened by bourbonut 3
  • note_angle acting weirdly

    note_angle acting weirdly

    Hey there !

    I guess I'm not using the function correctly... But I can't manage to make this work. Sorry if this is a dumb question !

    In the scheme module, you implemented many useful note functions including "note_angle" : https://pymadcad.readthedocs.io/en/latest/reference/scheme.html#madcad.scheme.note_angle

    I try to use it to make the user create angles by clicking:

    <At each click on the 3D scene with the angle notation tool:>
                   if self.first_point is None:
                        self.first_point = self.ptat(pos)
                    elif self.second_point is None:
                        self.second_point = self.ptat(pos)
    
                        # Display the "AB" segment
                        measure_keys = self.make_measure(self.first_point, self.second_point)
                    else:
                        _third_point = self.ptat(pos)
    
                        # display the "BC" segment
                        measure_keys = self.make_measure(self.second_point, _third_point)
                        
                        # Compute the angle and display it
                        a1 = madcad.Axis(self.second_point, self.first_point)
                        a2 = madcad.Axis(self.second_point, _third_point)
                        note_angle = madcad.note_angle(a1, a2)
                        note_key = self.scene.add(note_angle)
    

    The "note_angle" function renders me something like that : image image

    I can't show it but it seems the measure indicates "81°" which is... not that far, but I am not sure about this value neither.

    Do you have any tip about what I may be doing wrong ?

    Thanks a lot (again) ! :)

    Have a good day !

    opened by Yarkane 2
  • `mesh.volume()` returns a vec3 instead of a number

    `mesh.volume()` returns a vec3 instead of a number

    This should probably be s = 0.0

    https://github.com/jimy-byerley/pymadcad/blob/029a859af9b97792c3e033b0d0a87c8525531dae/madcad/mesh/mesh.py#L401

    The only thing added to it is a determinant, which is a scalar, not a vec3. Also, this function could just use a return sum(...).

    opened by coderforlife 2
  • Mac OS m-1 install

    Mac OS m-1 install

    Hello,

    I've been trying to get the module installed on a Mac OS m-1. I guess a few things here.

    First, python is currently miniconda for me [when running which python, the top of the list is conda].

    I tried installing using pip with a non condo bistro, and it has the following issue with PyQt5: AttributeError: module 'sipbuild.api' has no attribute 'prepare_metadata_f

    I tried updating pip to the latest and retried, no go. An article on the net shows us how to do this with a rosetta2 terminal session, still no go.

    So I tried getting into the condo environment with: Honda activate tf (tf being my environment) and ran pip install --upgrade pip

    All my condo packages got upgraded, and in there PyQt5 is available.

    Finally, running pip install pymadcad after having installed all dependencies, it's stuck at: Using cached PyQt5-5.15.7.tar.gz (3.2 MB) Installing build dependencies ... done Getting requirements to build wheel ... done Preparing metadata (pyproject.toml) ... -

    It's been stuck there for over 10 minutes now so I expect it to be an issue.

    Anyone successfully installed pyMADCAD on a Mac OS m-1?

    opened by triple7 1
  • added shell.nix

    added shell.nix

    Added a shell for the convenience of nixos users. This file will be helpfull for nixos user who just wants use pymadcad and for those who want to contribute.

    resolves #59

    opened by GlennWSo 5
  • missing how to install/use pymadcad on nixos

    missing how to install/use pymadcad on nixos

    hi

    As nixos user who wants to use this package and contribute to i need an install instruction.

    Since nixos is linux distro, but very different from the most common distros the "pip install" instruction installation will be insufficient for a nixos system.

    opened by GlennWSo 0
  • `chamfer` and `bevel` not accepted on wire extremities

    `chamfer` and `bevel` not accepted on wire extremities

    Currently, a bevel() works on any double-sided points of a Web and a Wire. However Wire's extremities might be considered double-sided points as well when Wire.closed = True and bevel() currently does not consider that.

    from madcad import *
    
    corner = 0   # index 0 in the wire is not accepted, nor -1,  any other place is fine
    
    outline = regon(Axis(O,Z), 1, 5)
    bevel(outline, [corner], ('width', 0.3))
    
    show([ outline ])
    
    Traceback (most recent call last):
      File "/tmp/test.py", line 4, in <module>
        bevel(outline, [0], ('width', 0.3))
      File "/usr/lib/python3.8/functools.py", line 875, in wrapper
        return dispatch(args[0].__class__)(*args, **kw)
      File "/home/jimy/.local/lib/python3.8/site-packages/madcad/cut.py", line 939, in wire_bevel
        cuts = set(wire_multicut(wire, points, cutter))
      File "/home/jimy/.local/lib/python3.8/site-packages/madcad/cut.py", line 890, in wire_multicut
        raise MeshError('a chamfer cannot have only one side')
    madcad.mesh.container.MeshError: a chamfer cannot have only one side
    

    with corner = 1 we get the expected behavior image

    bug enhancement good first issue 
    opened by jimy-byerley 0
  • Boolean diff produces incorrect mesh

    Boolean diff produces incorrect mesh

    Hi

    Im been testing boolean operations, to see if i can use this lib for my next project.

    I set up my test to avoid coplanar faces between the base mesh and the tool mesh, but i still ran into issues :-(

    Depending the resolution i choose when generating RandomHills, The boolean opeations will sometimes create mesh with some anomalies. When run my test case: boolean op starts fail on randomhills with 30x30 resoultion

    what im trying to diff

    random body, cutting tool

    The anomalies

    At first glance the result seems fine but the mesh is no longer a closed envelope. And with when looking carefully at the mesh, there is a long edge that should be divided more.

    seemsFine detailView

    code:

    import madcad as cad
    from madcad import dvec3, Axis
    
    import pyvista as pv
    import numpy as np
    
    
    def poly2mad(poly: pv.PolyData) -> cad.Mesh:
        """
        Helper to convert pyvista.PolyData to madcad
        """
        assert poly.n_faces > 0
        tri = poly.triangulate()  # avoid mutation and make all faces tri
        faces = tri.faces.reshape((-1, 4))[:, 1:].tolist()
        points = tri.points.tolist()
    
        mesh = cad.Mesh(points, faces)
        mesh.check()
        assert mesh.isvalid()
        assert mesh.issurface()
        return mesh
    
    
    def mad2poly(mesh: cad.Mesh) -> pv.PolyData:
        """
        helper to convert madcad.Mesh to pyvista.PolyData
        """
        face_arr = np.array([tuple(v) for v in mesh.faces])
        faces = np.pad(
            face_arr,
            pad_width=((0, 0), (1, 0)),
            constant_values=3,
        ).ravel()
    
        points = np.array([tuple(v) for v in mesh.points])
    
        poly = pv.PolyData(points, faces)
        return poly
    
    
    def randsurf(res=30, seed=1, **kwargs) -> cad.Mesh:
        """
        Creates a surface with random hills
        """
        poly = pv.ParametricRandomHills(
            u_res=res, v_res=res, w_res=res, randomseed=seed, **kwargs
        )
        return poly2mad(poly)
    
    
    def inspect(mesh: cad.Mesh, **kwargs):
        poly = mad2poly(mesh)
        edges = poly.extract_feature_edges(
            feature_edges=False, non_manifold_edges=False, manifold_edges=False
        )
        pmesh = pv.PolyData(edges.points)
        p = pv.Plotter()
        p.add_mesh(poly)
        p.add_mesh(edges, color="red", line_width=2)
        p.add_mesh(pmesh, color="blue", point_size=9.0)
        p.show(**kwargs)
        print(poly)
        print("poly n open edges", poly.n_open_edges)
        print("poly is manifold", poly.is_manifold)
        print("diff1 is envelope?", mesh.isenvelope())
    
    
    def test_boolean(res=30, dbg=False):
        """
        Test boolean operations robustness with a operations on a random generated Mesh
        """
        surf1 = randsurf(res=res, seed=1)
        axis1 = Axis(dvec3(0, 10, -1), dvec3(0, 0, 1))
        plane1 = cad.square(axis1, 20)
        ex1 = cad.extrusion(dvec3(0, 0, -10), surf1)
    
        assert ex1.isvalid()
        assert ex1.issurface()
        assert ex1.isenvelope()
        if dbg:
            cad.show([ex1, plane1])
    
        diff1 = cad.difference(ex1, plane1)
        if dbg:
            cad.show([diff1])
            inspect(diff1, title=f"Boolean diff with RandomHills resolution {res} * {res}")
    
        assert diff1.isvalid()
        assert diff1.issurface()
        assert diff1.isenvelope()
    
    
    if __name__ == "__main__":
        # booleans work on low res
        for n in range(5, 55, 5):
    
            try:
                test_boolean(res=n)
                print(f"resolution: {n} worked")
            except AssertionError:
                test_boolean(res=n, dbg=True)  # set dbg to inspect what is going on
                print(f"resolution: {n} failed")
    
    
    opened by GlennWSo 7
  • Errors on MacOSX

    Errors on MacOSX

    Hi,

    Is there a known issue using pymadcad on MacOsX? I'm trying to run an example from your "examples" folder and I receive the following errors:

    qt.qpa.openglcontext: Could not create NSOpenGLContext with shared context, falling back to unshared context.
    Traceback (most recent call last):
      File "/Users/jeromegout/dev/david/implantology/.venv/lib/python3.9/site-packages/madcad/rendering.py", line 1099, in paintGL
        self.render()
      File "/Users/jeromegout/dev/david/implantology/.venv/lib/python3.9/site-packages/madcad/rendering.py", line 981, in render
        ViewCommon.render(self)
      File "/Users/jeromegout/dev/david/implantology/.venv/lib/python3.9/site-packages/madcad/rendering.py", line 712, in render
        self.uniforms['proj'] = proj = self.projection.matrix(w/h, self.navigation.distance)
    ZeroDivisionError: division by zero
    [1]    8975 abort      /Users/jeromegout/dev/david/implantology/.venv/bin/python 
    

    It seems that is related to OpenGL. Any clue or advice

    Thanks in advance Jerome

    bug compatibility 
    opened by jeromegout 25
Releases(v0.15.1)
  • v0.15.1(Dec 21, 2022)

  • v0.15(Dec 20, 2022)

    It seems there is enough changes for a new release !

    new features

    • added text.text() to generate surface meshes and outline webs from text strings, using custom fonts. checkout the docs !
    • removed text.Text as not very useful
    • Scheme instances are no longer filtered by display_annotations=False, instead Solid['annotations'] are as long as the Solid is not selected
    • added part slots functions in madcad.standard

    bug fixes

    • fixed Web.frontiers() and Mesh.frontiers() when single-sided edges are demanded (None in group list)
    • fixed and improved stfloor() and stceil()
    • fixed Container.*near()
    • fixed occasional near-infinite loops in boolean operations
    Source code(tar.gz)
    Source code(zip)
  • v0.14(Nov 5, 2022)

    This version brings some new features and few fixes

    • added helical bevel gears thanks to @bourbonut
    • added stfloor() and stceil() to help getting human-friendly distances in automatically computed results
    • fixed wrong variable names in Mesh.surface(), Mesh.volume(), Wire.surface()
    • fixed wrong pose for sub-group displays before any solid move
    Source code(tar.gz)
    Source code(zip)
  • v0.13.2(Sep 25, 2022)

  • v0.13(Sep 17, 2022)

    This new version brings few new meshing functions, and a big quality-of-life change regarding surface selections in meshes.

    new features

    • added module madcad.hull and everything under it !

    • added generation.expand()

    • new Mesh inner identification system.

      This feature concerns all data types in madcad.mesh and adds mainly the method .qualify() that helps labeling groups which helps selecting them afterward. check the docs

    • added wrapper for pickle files in madcad.io

    • schemes displays are now highlighted when selected

    • functions generating finished parts are now returning a Solid ready for assembly

    • added support for partial kinematic joint definition in Solid.place()

    bug fixes

    • fixed boolean operations propagation failing sometimes
    • fixed some floating point precision issues in madcad.triangulation
    • fixed some floating point precision issues in madcad.boolean
    • fixed wrong argument modification in scaledir()
    • fixed wrong view-controled Solid move in case of solids included in solids
    • fixed View() and show() not using all their arguments
    • fixed Orthographic projection
    • fixed screen size spaces in schemes, hence changing the previous schemes to much bigger (now the screen coordinates are true pixels)
    • fixed scheme.halo_screen()

    breaking changes

    • removed Solid.itransform()
    • changed behavior of Scene.display(): it now accepts the former Display to replace or update
    Source code(tar.gz)
    Source code(zip)
  • v0.12(May 8, 2022)

    new features

    • added linrange to generate uniformly spaced iterators of floats
    • mat3, mat4, quat are now displayable
    • added generation functions for common shapes: cylinder(), cone(), pyramid()

    bug fixes

    • fixed bug of wire, web when working with instances of typedlist
    • fixed some triangulation bugs
    Source code(tar.gz)
    Source code(zip)
  • v0.11(Feb 10, 2022)

    This version is one of the most important version of the lasts year :champagne: : it brings arrex a python module created especially for the needs of the madcad project (even though it is meant for a wider variety of tasks). It provides list-like containers that stores elements in buffers. allowing future big optimizations of madcad.

    new features

    • Thanks to @Gigahawk we now have a headless rendering option (#18) ! which means we can perform 3d rendering without having to display a window and manually take a screenshot. The documentation will come soon here
    • show() now accepts an existing scene as argument (It requires the openGL context to be shared)
    • All point, face, or edge lists are now of type typedlist, allowing very fast conversion (without copy) to/from numpy :fireworks:

    breaking changes

    • All point, face, or edge lists are now instances of arrex.typedlist. This should not be a point it you just used your meshes from the Mesh methods, or used its attributes like Mesh.points through their list methods because typedlist behaves just like list in most cases. There is just few points to consider:

      • If you were using type checks like isinstance(mesh.points, list) you should put typedlist instead
      • If you were using strided slicing (such as mesh.points[a:b:step]) it won't work any more since not yet supported by arrex
      • slicing a typedlist doesn't return a copy by a view of the original one (for efficency reasons). If you experience troubles with this change, use deepcopy() after slicing
    • ArcCentered(axis, a, b).mesh() now always return a mesh that reachs a and b even if the result is not an arc. This helps to have closed oulines even when the solver is set with a bad precision.

    fixes

    • fixed some rare boolean operation issues
    Source code(tar.gz)
    Source code(zip)
  • v0.10.2(Jan 4, 2022)

    mostly fixes for the last release, but also some new small nice features

    features

    • note_bounds() and note_radius() are added for measuring
    • added intuitive transformation operations Kinematic._add__() and Kinematic.transform()
    • reworked the constraint solving system, it now uses a scipy least squares method, which is much faster and precise than before

    fixes

    • display issue with the color of webs and wire
    • the last release was not installable due to some parasiting file I packed with (I sincerely apologize for this)
    Source code(tar.gz)
    Source code(zip)
  • v0.10.0(Dec 25, 2021)

    New version with some fixes with new features !

    new features

    • refactoring of the boolean API, removing functions like booleanwith that were unclear and not convenient.

    • boolean operations are now possible between webs.

      In the spirit of boolean operations with meshes, that were playing cutting/stitching Meshes as envelopes depending on the volume operations, the Web boolean operations are cutting/stitching webs as surface contours. This allows to use pierce, boolean, union, difference, intersection with webs

    • some boolean operations are possible between web and mesh

      This allows to use pierce with webs

    • bevel gears !

      The submodule gear brings bevel gears and their source spherical profiles. All the explaining equations will come in the docs soon. Check the docs

    • minor improvements to reverse.segmentation

    bug fixes

    • touchscreen event handling
    • surface and wire layering issues when the objects are too small (<1e-2) or too bing (>100)
    • visual boundingbox issues with Solid
    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Oct 3, 2021)

    New release bringing some new features mostly regarding the Solids manipulation

    New featues:

    • part placement deduced from surface types (like in most CAD programs): docs
    • exploded view of solids: docs
    • segmentation of surfaces on imported meshes docs This submodule is for all what regards reverse engineering and also provided functions to deduce joints and surfaces from raw meshes

    Breaking changes:

    • Solid.transform is not inplace anymore, it will return a new Solid instead, use Solid.itransform for the old behavior

    Fixes:

    • wrong angle use in gear.repeat_circular in case of non planar profile
    • scheme.Scheme matrices issue due to column vs line major arrays
    • voxel density display broken when non-cubic
    Source code(tar.gz)
    Source code(zip)
  • v0.8.4(Jun 21, 2021)

  • v0.8.3(Jun 21, 2021)

  • v0.8.2(Jun 20, 2021)

  • v0.8.1(Jun 20, 2021)

  • v0.8(Jun 19, 2021)

    Finally the next release of our module ! It comes with many new feature. Focus is done on standard parts

    I am also glad to welcome a new contributor: @bourbonut ! who has coded a lot in the new submodule gear. So let's celebrate !

    new features

    • new submodule madcad.standard provide functions to generate many of the most common standard parts (like screws, nuts, coils ...) Checkout the docs !

    • new submodule madcad.gear provide functions to generate involute gears. Either ready to use or customizable. Checkout the docs !

    • all chamfer, bevel, multicut are now available for Mesh, Web and Wire

    • improved speed of cutting operations (chamfer, bevel, multicut)

    • added function boolean.pierce() to complete the collection of boolean operations

    • improved junction()

    • improved thicken()

    • extrusion() now performs any linear transformation as extrans

    • transform(float) is added to give a rescale matrix

    Plus many fixes ...

    breaking changes

    • Mesh.frontiers and Mesh.groupoutlines have been reworked

      Some related or redundant methods have been removed. The returned outlines are now oriented as often as possible.

    • Mesh.vertexnormals() now behaves differently for points on the outlines and for points in the middle of faces

      • points on the surface are computed as before with the neighbooring faces normals weighted by their angle
      • points on the outline only mix adjacent faces to the outline, making the resulting normal independent of the way the surface is triangulated
    • renamed multiple() -> repeat()

    Source code(tar.gz)
    Source code(zip)
  • v0.7(Mar 16, 2021)

    new features:

    • new primitives for splines: Interpolated and Softened
    • added io.cachefunc decorator to easily use temporary files
    • the config file is now a yaml file instead of a json, to incread readability
    • increased compatibility of constraints Parallel, Angle, Distance
    • improved the way to use Kinematic and Solid (see the docs)
    • renamed some joints definitions
    • renamed Torsor into Screw the proper mathematical term
    • new mesh methods:
      • Mesh.orient
      • Web.islands

    bug fixes:

    • boolean operations : all known bugs fixed
    • many numeric issues and display issues fixed
    Source code(tar.gz)
    Source code(zip)
  • v0.6(Jan 20, 2021)

    new features:

    • better annotations and primtive constraints, see madcad.scheme
    • added many methods to Mesh
    • added mesh_distance
    • added ghost transparent display for surfaces improved Web rendering

    breaking change

    • project, unproject, noproject are now insensitive to the direction length ! (insensitive as long as direction is not too close to length 0) this should be much more convenient, and more efficient on average, but it can eventually breaks existing code that were not using normalized directions.
    Source code(tar.gz)
    Source code(zip)
  • v0.5(Dec 13, 2020)

    new features: junctions and blendings

    the new blending submodule brings mainly the following functions:

    • junction(*interfaces, ...) to create surfaces between outlines
    • blendloop(inteface, ...) to fill a loop
    • blendpair(*interfaces, ...) to fill between 2 lines

    all these support different ways to set the tangents, and different way to specify the line interfaces, checkout the doc !

    regressions

    the ability to blend between 2 curves by adding the necessary subdivisions have been removed in favor of the blending module, it should be reintroduced in the next releases.

    Source code(tar.gz)
    Source code(zip)
    pymadcad-0.5-cp38-cp38-linux_x86_64.whl(1.10 MB)
    pymadcad-0.5.tar.gz(1.07 MB)
  • v0.4(Oct 9, 2020)

    new rendering pipeline

    This new release brings:

    • few changes in the API
    • big change in the API and implementation regarding the display
    • automatic adaptation of the 3D view to the system theme

    The new rendering system give a very similar look to objects, but behaves very differently inside. Most of the advantages of this change are coming in the next features that this rendering system allows.

    • the displays can be parented
      • allowing local coordinates, grouping objects
      • the events are dispatched descending the parenting tree
      • the display order is independent of the parenting
      • the kinematic displays benefits from this, having a local space for each solid
    • the scene content is independent of the viewer widget
      • the former View class is splitted across View(Qt widget) and Scene (gui-agnostic scene)
      • allows to manage one only scene used by several view widgets
      • decreasing GPU memory usage
    • quickdisplay is improved and renamed show
    Source code(tar.gz)
    Source code(zip)
  • v0.3(Sep 5, 2020)

    chamfers and bevels

    Here is the new release, with most of the work of the last month !

    changes:

    • added general purpose chamfers and bevels, now working and any set of edges and points (see documentation)
    • added some useful functions to mathutils
    • changed some functions signatures, especially web and wire
    • other minor improvements and bug fixes
    Source code(tar.gz)
    Source code(zip)
    pymadcad-0.3.tar.gz(1.06 MB)
  • v0.2(Aug 2, 2020)

    first release marks the first published version of this library. Features working (even if not complete for some):

    • line primitives
    • solver for primitive constraints
    • mesh/wire data types
    • surface generation functions (extrusion, revolution, ...)
    • boolean operations
    • chamfer/bevel operations
    • kinematic joints definitions
    • kinematic solver and interactive manipulation
    • 3D display for almost any madcad object
    • Qt 3D scene widget
    Source code(tar.gz)
    Source code(zip)
Owner
jimy byerley
jimy byerley
Explain yourself! Interrogate a codebase for docstring coverage.

interrogate: explain yourself Interrogate a codebase for docstring coverage. Why Do I Need This? interrogate checks your code base for missing docstri

Lynn Root 435 Dec 29, 2022
💯 Coolest snippets

nvim-snippets This was originally included in my personal Neovim setup, but I didn't like having all the snippets there so I decided to have them sepa

Eliaz Bobadilla 6 Aug 31, 2022
Some code that takes a pipe-separated input and converts that into a table!

tablemaker A program that takes an input: a | b | c # With comments as well. e | f | g h | i |jk And converts it to a table: ┌───┬───┬────┐ │ a │ b │

CodingSoda 2 Aug 30, 2022
Fun interactive program to sort a list :)

LHD-Build-Sort-a-list Fun interactive program to sort a list :) Inspiration LHD Build Write a script to sort a list. What it does It is a menu driven

Ananya Gupta 1 Jan 15, 2022
Automatically open a pull request for repositories that have no CONTRIBUTING.md file

automatic-contrib-prs Automatically open a pull request for repositories that have no CONTRIBUTING.md file for a targeted set of repositories. What th

GitHub 8 Oct 20, 2022
Swagger UI is a collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.

Introduction Swagger UI allows anyone — be it your development team or your end consumers — to visualize and interact with the API’s resources without

Swagger 23.2k Dec 29, 2022
A website for courses of Major Computer Science, NKU

A website for courses of Major Computer Science, NKU

Sakura 0 Oct 06, 2022
Build AGNOS, the operating system for your comma three

agnos-builder This is the tool to build AGNOS, our Ubuntu based OS. AGNOS runs on the comma three devkit. NOTE: the edk2_tici and agnos-firmare submod

comma.ai 21 Dec 24, 2022
Easy OpenAPI specs and Swagger UI for your Flask API

Flasgger Easy Swagger UI for your Flask API Flasgger is a Flask extension to extract OpenAPI-Specification from all Flask views registered in your API

Flasgger 3.1k Jan 05, 2023
MkDocs plugin for setting revision date from git per markdown file

mkdocs-git-revision-date-plugin MkDocs plugin that displays the last revision date of the current page of the documentation based on Git. The revision

Terry Zhao 48 Jan 06, 2023
Get link preview of a website.

Preview Link You may have seen a preview of a link with a title, image, domain, and description when you share a link on social media. This preview ha

SREEHARI K.V 8 Jan 08, 2023
Numpy's Sphinx extensions

numpydoc -- Numpy's Sphinx extensions This package provides the numpydoc Sphinx extension for handling docstrings formatted according to the NumPy doc

NumPy 234 Dec 26, 2022
Generate modern Python clients from OpenAPI

openapi-python-client Generate modern Python clients from OpenAPI 3.x documents. This generator does not support OpenAPI 2.x FKA Swagger. If you need

555 Jan 02, 2023
Show Rubygems description and annotate your code right from Sublime Text.

Gem Description for Sublime Text Show Rubygems description and annotate your code. Just mouse over your Gemfile's gem definitions to show the popup. s

Nando Vieira 2 Dec 19, 2022
Python Eacc is a minimalist but flexible Lexer/Parser tool in Python.

Python Eacc is a parsing tool it implements a flexible lexer and a straightforward approach to analyze documents.

Iury de oliveira gomes figueiredo 60 Nov 16, 2022
Sphinx-performance - CLI tool to measure the build time of different, free configurable Sphinx-Projects

CLI tool to measure the build time of different, free configurable Sphinx-Projec

useblocks 11 Nov 25, 2022
Main repository for the Sphinx documentation builder

Sphinx Sphinx is a tool that makes it easy to create intelligent and beautiful documentation for Python projects (or other documents consisting of mul

5.1k Jan 02, 2023
More detailed upload statistics for Nicotine+

More Upload Statistics A small plugin for Nicotine+ 3.1+ to create more detailed upload statistics. ⚠ No data previous to enabling this plugin will be

Nick 1 Dec 17, 2021
204-python-string-21BCA90 created by GitHub Classroom

204-Python This repository is created for subject "204 Programming Skill" Python Programming. This Repository contain list of programs of python progr

VIDYABHARTI TRUST COLLEGE OF BCA 6 Mar 31, 2022
Repository for learning Python (Python Tutorial)

Repository for learning Python (Python Tutorial) Languages and Tools 🧰 Overview 📑 Repository for learning Python (Python Tutorial) Languages and Too

Swiftman 2 Aug 22, 2022