I built a model that has several intersecting tubes. Where two tubes intersect, I have used a Boolean cut function to cope one of the tubes into the other. In general, the operation works as expected, but sometimes it does not work properly. I have built a simplified model with two tubes to illustrate an instance where it does not work (Python code below). On the coped tube, there are lines where the cuts should be, but no material has been removed. I have found other people who have observed similar problems (https://forum.freecadweb.org/viewtopic.php?t=16824 & https://forum.freecadweb.org/viewtopic.php?t=10225), but the solutions proposed don’t work for this case. I observe the same results in v0.18.16110. Any suggestions on how to fix this problem would be much appreciated! Thanks.
Cheers,
Doug
Code: Select all
import os
import sys
import Part
import PartDesign
import Draft
import DraftGeomUtils
import math
import numpy as np
import time
from FreeCAD import Base
from Part import Wire, Face, Solid
from math import cos, sin, tan, radians, asin, acos, atan, atan2, degrees
d = App.newDocument("Tube_Cutting")
g = FreeCADGui.ActiveDocument
V = App.Vector
x = V(1,0,0)
y = V(0,1,0)
z = V(0,0,1)
Origin = V(0,0,0)
def makeMember(MemberName, MemberCL, MemberOR, MemberIR, Transparency, TubeVisibility=True):
# print('MakeMember: ',MemberName)
TubeName = MemberName+'Tube'
OuterName = MemberName+'Outer'
MemberOuterCyl = MemberOuter(MemberCL, MemberOR)
MemberInnerCyl = MemberOuter(MemberCL, MemberIR)
MemberTube = MemberOuterCyl.cut(MemberInnerCyl)
d.addObject("Part::Feature",OuterName).Shape = Part.Solid(MemberOuterCyl)
d.addObject("Part::Feature",TubeName).Shape = MemberTube
MemberGUI = getattr(g,TubeName)
MemberGUI.Transparency=Transparency
MemberGUI.Visibility=TubeVisibility
MemberOuterGUI = getattr(g,OuterName)
MemberOuterGUI.Visibility=False
return(MemberTube)
def MemberOuter(MemberCL, MemberOR):
# print('MemberOuter')
OuterShellSegmentL = []
StartP = MemberCL.Vertexes[0].Point
EndP = MemberCL.Vertexes[-1].Point
MemberLen = StartP.distanceToPoint(EndP)
Tolerance = MemberLen/10**6
for CLEdge in MemberCL.Edges:
OuterShellSegmentL.append((Part.makeTube(CLEdge,MemberOR)))
# print(OuterShell)
EndWire=makeEndFace(OuterShellSegmentL[0], StartP, Tolerance).OuterWire
Tube = Part.Wire(MemberCL).makePipeShell([EndWire],True,True)
return(Tube)
def makeEndFace(Shell, StartP, Tolerance):
# print(MemberName)
for ShellEdge in Shell.Edges:
# print('ShellEdge ',ShellEdge)
if ShellEdge.Closed: #Found end edge
# print('Closed Edge')
CircularFace = Part.Face(Part.Wire(ShellEdge)) # Make circular end face
if CircularFace.isInside(StartP,Tolerance,True): #Check if face contains start point
# print('StartFace')
return(CircularFace)
else:
print('No face found')
return()
MemberVisibility = False
MemberTransparency = 0
CLVisibility = False
MemberOR = 35/2
MemberIR = 33.5/2
MemberStart = V(1430.0, -415.3, 909.0)
MemberEnd = V(804.2, 478.4, 897.0)
MemberMid = V((MemberStart+MemberEnd)/2+V(0,0,36))
MemberCL = Part.Wire(Part.Arc(MemberStart,MemberMid,MemberEnd).toShape())
d.addObject("Part::Feature",'MemberCL').Shape = MemberCL
MemberTube = makeMember('Member', MemberCL, MemberOR, MemberIR, MemberTransparency, MemberVisibility)
d.addObject("Part::Feature",'Member1CL').Shape = d.MemberCL.Shape.mirror(Origin,y)
Member1Tube = makeMember('Member1', d.Member1CL.Shape, MemberOR, MemberIR, MemberTransparency, MemberVisibility)
print('Cut tubes')
Member1Cut = d.Member1Tube.Shape.cut(d.MemberOuter.Shape)
d.addObject("Part::Feature",'Member1Cut').Shape = Member1Cut
g.MemberCL.Visibility=CLVisibility
g.Member1CL.Visibility=CLVisibility
# g.MemberTube.Visibility=False
# g.Member1Tube.Visibility=False
g.activeView().viewIsometric()
g.ActiveView.fitAll()
d.recompute()
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.16945 (Git)
Build type: Release
Branch: master
Hash: d818a9638424a934bd9da74d187a1af4cb773f05
Python version: 3.6.8
Qt version: 5.12.1
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: English/Canada (en_CA)