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
In this Github repository I will share my freqtrade files with you. I want to help people with this repository who don't know Freqtrade so much yet.

My Freqtrade stuff In this Github repository I will share my freqtrade files with you. I want to help people with this repository who don't know Freqt

Simon Kebekus 104 Dec 31, 2022
A simple malware that tries to explain the logic of computer viruses with Python.

Simple-Virus-With-Python A simple malware that tries to explain the logic of computer viruses with Python. What Is The Virus ? Computer viruses are ma

Xrypt0 6 Nov 18, 2022
A Material Design theme for MkDocs

A Material Design theme for MkDocs Create a branded static site from a set of Markdown files to host the documentation of your Open Source or commerci

Martin Donath 12.3k Jan 4, 2023
Grokking the Object Oriented Design Interview

Grokking the Object Oriented Design Interview

Tusamma Sal Sabil 2.6k Jan 8, 2023
A powerful Sphinx changelog-generating extension.

What is Releases? Releases is a Python (2.7, 3.4+) compatible Sphinx (1.8+) extension designed to help you keep a source control friendly, merge frien

Jeff Forcier 166 Dec 29, 2022
A simple USI Shogi Engine written in python using python-shogi.

Revengeshogi My attempt at creating a USI Shogi Engine in python using python-shogi. Current State of Engine Currently only generating random moves us

null 1 Jan 6, 2022
A website for courses of Major Computer Science, NKU

A website for courses of Major Computer Science, NKU

Sakura 0 Oct 6, 2022
Contains the assignments from the course Building a Modern Computer from First Principles: From Nand to Tetris.

Contains the assignments from the course Building a Modern Computer from First Principles: From Nand to Tetris.

Matheus Rodrigues 1 Jan 20, 2022
This is a repository for "100 days of code challenge" projects. You can reach all projects from beginner to professional which are written in Python.

100 Days of Code It's a challenge that aims to gain code practice and enhance programming knowledge. Day #1 Create a Band Name Generator It's actually

SelenNB 2 May 12, 2022
An open-source script written in python just for fun

Owersite Owersite is an open-source script written in python just for fun. It do

大きなペニスを持つ少年 7 Sep 21, 2022
EasyMultiClipboard - Python script written to handle more than 1 string in clipboard

EasyMultiClipboard - Python script written to handle more than 1 string in clipboard

WVlab 1 Jun 18, 2022
This is a small project written to help build documentation for projects in less time.

Documentation-Builder This is a small project written to help build documentation for projects in less time. About This project builds documentation f

Tom Jebbo 2 Jan 17, 2022
A collection of simple python mini projects to enhance your python skills

A collection of simple python mini projects to enhance your python skills

PYTHON WORLD 12.1k Jan 5, 2023
A Python library for setting up projects using tabular data.

A Python library for setting up projects using tabular data. It can create project folders, standardize delimiters, and convert files to CSV from either individual files or a directory.

null 0 Dec 13, 2022
A simple tutorial to get you started with Discord and it's Python API

Hello there Feel free to fork and star, open issues if there are typos or you have a doubt. I decided to make this post because as a newbie I never fo

Sachit 1 Nov 1, 2021
SCTYMN is a GitHub repository that includes some simple scripts(currently only python scripts) that can be useful.

Simple Codes That You Might Need SCTYMN is a GitHub repository that includes some simple scripts(currently only python scripts) that can be useful. In

CodeWriter21 2 Jan 21, 2022
Fast syllable estimation library based on pattern matching.

Syllables: A fast syllable estimator for Python Syllables is a fast, simple syllable estimator for Python. It's intended for use in places where speed

ProseGrinder 26 Dec 14, 2022
charcade is a string manipulation library that can animate, color, and bruteforce strings

charcade charcade is a string manipulation library that can animate, color, and bruteforce strings. Features Animating text for CLI applications with

Aaron 8 May 23, 2022
Gaphor is the simple modeling tool

Gaphor Gaphor is a UML and SysML modeling application written in Python. It is designed to be easy to use, while still being powerful. Gaphor implemen

Gaphor 1.3k Jan 3, 2023