CadQuery / cadquery

A python parametric CAD scripting framework based on OCCT
https://cadquery.readthedocs.io
Other
3.21k stars 293 forks source link

Cutting a Cylinder with a line (intersect) #1334

Open Zorcas opened 1 year ago

Zorcas commented 1 year ago

Hi everyone,

i am trying to change an existing script that calculates a quite complex geometry based on a FREECAD hook in python to use the cadquery package.

The biggest difference i saw was the information saved in the variables. E.g. when i try to get information of my object i allways have to use functions and can't just use obj.BoundBox.

My Problem: I am trying to intersect a line with a cylinder and get the start and end point of the intersection-line aswell as its length. In my FREECAD python script version it was programmed as follows:

    total_length=0
    length=[]
    for i in range(0,len(struts)):
        line=Part.makeLine((struts[i][0],struts[i][1],struts[i][2]),(struts[i][3], struts[i][4], struts[i][5])) #create a FreeCAD Line
        cut_line = cylinder.common(line) #cut with the cylinder to remove excess

        if len(cut_line.Vertexes)==2:
            # this saves the start and end point of the line which was cut by the cylinder
            struts[i] = [cut_line.Vertexes[0].Point[0],cut_line.Vertexes[0].Point[1],cut_line.Vertexes[0].Point[2],cut_line.Vertexes[1].Point[0],cut_line.Vertexes[1].Point[1],cut_line.Vertexes[1].Point[2]]

        length.append(cut_line.Length) #create vector with length of the lines
        total_length+=cut_line.Length #add all these lengths
        del line
        del cut_line

I cannot find any functions to achieve the same with cadquery.

Thanks for your help!

Best regards,

Mischa

adam-urbanczyk commented 1 year ago

Here is how you could do it:

from cadquery import *

c = Workplane().cylinder(5,1)
l = Workplane().moveTo(5,0).lineTo(-5,0)
res =  c.intersect(l).edges().val()

start = res.startPoint()
stop = res.endPoint()
length = res.Length()
Zorcas commented 1 year ago

Here is how you could do it:

from cadquery import *

c = Workplane().cylinder(5,1)
l = Workplane().moveTo(5,0).lineTo(-5,0)
res =  c.intersect(l).edges().val()

start = res.startPoint()
stop = res.endPoint()
length = res.Length()

Thank you very much! I solved the problem as follows:

total_length=0
    length=[]
    for i in range(0,len(struts)):
        line= cq.Edge.makeLine((struts[i][0],struts[i][1],struts[i][2]),(struts[i][3], struts[i][4], struts[i][5])) #create a FreeCAD Line
        cut_line = cq.Workplane(cylinder).intersect(cq.Workplane(line)).edges().val() #cut with the cylinder to remove excess

        if cut_line.Length() !=0:
            # this saves the start and end point of the line which was cut by the cylinder
            struts[i] = [cut_line.startPoint().x,cut_line.startPoint().y,cut_line.startPoint().z,cut_line.endPoint().x,cut_line.endPoint().y,cut_line.endPoint().z]

        length.append(cut_line.Length()) #create vector with length of the lines
        total_length+=cut_line.Length() #add all these lengths
        del line
        del cut_line

maybe you can help me with my next problem aswell :)

I create Solids on those lines with a triangle crossshape. After that i want to check if those solids are superimposing with another cylinder i just created before. I tried this using:

if cq.Workplane(res_cylinder).intersect(cq.Workplane(all_strut_element)).edges().val().Length() > 0:

When there is no intersection I cannot call the Length()-function. Is there an easy way to check if the 2 objects intersect?

Best regards, Mischa

lorenzncode commented 1 year ago

Is there an easy way to check if the 2 objects intersect?

If no intersection, the compound is empty:

from cadquery import *

c = Workplane().cylinder(5,1)
#l = Workplane().moveTo(5,0).lineTo(-5,0)
l = Workplane().moveTo(10,0).lineTo(20,0) 
res =  c.intersect(l)

if res.val():
    res = res.edges().val()
else:
    print("empty compound")