Merge branch 'master' into pathpocketshape_fix
This commit is contained in:
@@ -258,10 +258,16 @@ class CommandAddonManager:
|
||||
|
||||
from PySide import QtGui
|
||||
self.repos.append(addon_repo)
|
||||
if addon_repo[2] == 1 :
|
||||
self.dialog.listWorkbenches.addItem(QtGui.QListWidgetItem(QtGui.QIcon(":/icons/button_valid.svg"),str(addon_repo[0]) + str(" ("+translate("AddonsInstaller","Installed")+")")))
|
||||
import AddonManager_rc
|
||||
addonicon = QtGui.QIcon(":/icons/" + addon_repo[0] + "_workbench_icon.svg")
|
||||
if addonicon.isNull():
|
||||
addonicon = QtGui.QIcon(":/icons/Group.svg")
|
||||
if addon_repo[2] == 1:
|
||||
item = QtGui.QListWidgetItem(addonicon,str(addon_repo[0]) + str(" ("+translate("AddonsInstaller","Installed")+")"))
|
||||
item.setBackground(QtGui.QBrush(QtGui.QColor(0,182,41)))
|
||||
self.dialog.listWorkbenches.addItem(item)
|
||||
else:
|
||||
self.dialog.listWorkbenches.addItem(QtGui.QListWidgetItem(QtGui.QIcon(":/icons/Group.svg"),str(addon_repo[0])))
|
||||
self.dialog.listWorkbenches.addItem(QtGui.QListWidgetItem(addonicon,str(addon_repo[0])))
|
||||
|
||||
def show_information(self, label):
|
||||
|
||||
@@ -358,7 +364,9 @@ class CommandAddonManager:
|
||||
from PySide import QtGui
|
||||
self.macros.append(macro)
|
||||
if macro.is_installed():
|
||||
self.dialog.listMacros.addItem(QtGui.QListWidgetItem(QtGui.QIcon(":/icons/button_valid.svg"), macro.name + str(' (Installed)')))
|
||||
item = QtGui.QListWidgetItem(QtGui.QIcon(":/icons/applications-python.svg"), macro.name + str(' (Installed)'))
|
||||
item.setBackground(QtGui.QBrush(QtGui.QColor(0,182,41)))
|
||||
self.dialog.listMacros.addItem(item)
|
||||
else:
|
||||
self.dialog.listMacros.addItem(QtGui.QListWidgetItem(QtGui.QIcon(":/icons/applications-python.svg"),macro.name))
|
||||
|
||||
@@ -400,15 +408,13 @@ class CommandAddonManager:
|
||||
"shows or hides the progress bar"
|
||||
|
||||
if state == True:
|
||||
self.dialog.listWorkbenches.setEnabled(False)
|
||||
self.dialog.listMacros.setEnabled(False)
|
||||
self.dialog.tabWidget.setEnabled(False)
|
||||
self.dialog.buttonInstall.setEnabled(False)
|
||||
self.dialog.buttonUninstall.setEnabled(False)
|
||||
self.dialog.progressBar.show()
|
||||
else:
|
||||
self.dialog.progressBar.hide()
|
||||
self.dialog.listWorkbenches.setEnabled(True)
|
||||
self.dialog.listMacros.setEnabled(True)
|
||||
self.dialog.tabWidget.setEnabled(True)
|
||||
if not (self.firsttime and self.firstmacro):
|
||||
self.dialog.buttonInstall.setEnabled(True)
|
||||
self.dialog.buttonUninstall.setEnabled(True)
|
||||
@@ -535,7 +541,7 @@ class CommandAddonManager:
|
||||
wb[2] = 0
|
||||
for macro in self.macros:
|
||||
if macro.is_installed():
|
||||
self.dialog.listMacros.addItem(QtGui.QListWidgetItem(QtGui.QIcon(":/icons/button_valid.svg"), macro.name + " ("+translate("AddonsInstaller","Installed")+")"))
|
||||
self.dialog.listMacros.addItem(item)
|
||||
else:
|
||||
self.dialog.listMacros.addItem(QtGui.QListWidgetItem(QtGui.QIcon(":/icons/applications-python.svg"),+macro.name))
|
||||
|
||||
@@ -548,7 +554,7 @@ class CommandAddonManager:
|
||||
w = self.dialog.listWorkbenches.item(i)
|
||||
if w.text().startswith(str(repo)):
|
||||
w.setText(str(repo) + str(" ("+translate("AddonsInstaller","Update available")+")"))
|
||||
w.setIcon(QtGui.QIcon(":/icons/debug-marker.svg"))
|
||||
w.setBackground(QtGui.QBrush(QtGui.QColor(182,90,0)))
|
||||
if not repo in self.doUpdate:
|
||||
self.doUpdate.append(repo)
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
IF (BUILD_GUI)
|
||||
PYSIDE_WRAP_RC(AddonManager_QRC_SRCS Resources/AddonManager.qrc)
|
||||
ENDIF (BUILD_GUI)
|
||||
|
||||
SET(AddonManager_SRCS
|
||||
Init.py
|
||||
InitGui.py
|
||||
@@ -12,14 +16,24 @@ SET(AddonManager_SRCS
|
||||
SOURCE_GROUP("" FILES ${AddonManager_SRCS})
|
||||
|
||||
ADD_CUSTOM_TARGET(AddonManager ALL
|
||||
SOURCES ${AddonManager_SRCS}
|
||||
SOURCES ${AddonManager_SRCS} ${AddonManager_QRC_SRCS}
|
||||
)
|
||||
|
||||
fc_copy_sources(AddonManager "${CMAKE_BINARY_DIR}/Mod/AddonManager" ${AddonManager_SRCS})
|
||||
|
||||
IF (BUILD_GUI)
|
||||
fc_target_copy_resource(AddonManager
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}/Mod/AddonManager
|
||||
AddonManager_rc.py)
|
||||
ENDIF (BUILD_GUI)
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${AddonManager_SRCS}
|
||||
${AddonManager_QRC_SRCS}
|
||||
DESTINATION
|
||||
Mod/AddonManager
|
||||
)
|
||||
|
||||
|
||||
|
||||
31
src/Mod/AddonManager/Resources/AddonManager.qrc
Normal file
31
src/Mod/AddonManager/Resources/AddonManager.qrc
Normal file
@@ -0,0 +1,31 @@
|
||||
<RCC>
|
||||
<qresource>
|
||||
<file>icons/A2plus_workbench-icon.svg</file>
|
||||
<file>icons/Airplane_workbench-icon.svg</file>
|
||||
<file>icons/Arch_Textures_workbench_icon.svg</file>
|
||||
<file>icons/BIM_workbench_icon.svg</file>
|
||||
<file>icons/BOLTS_workbench_icon.svg</file>
|
||||
<file>icons/cfd_workbench_icon.svg</file>
|
||||
<file>icons/Curves_workbench_icon.svg</file>
|
||||
<file>icons/Defeaturing_workbench_icon.svg</file>
|
||||
<file>icons/Dodo_workbench_icon.svg</file>
|
||||
<file>icons/EM_workbench_icon.svg</file>
|
||||
<file>icons/ExplodedAssembly_workbench_icon.svg</file>
|
||||
<file>icons/Fasteners_workbench_icon.svg</file>
|
||||
<file>icons/Flamingo_workbench_icon.svg</file>
|
||||
<file>icons/GDT_workbench_icon.svg</file>
|
||||
<file>icons/Gears_workbench_icon.svg</file>
|
||||
<file>icons/Glider_workbench_icon.svg</file>
|
||||
<file>icons/Kicad-StepUp-tools-workbench_icon.svg</file>
|
||||
<file>icons/Lattice2_workbench_icon.svg</file>
|
||||
<file>icons/Lithophane_workbench_icon.svg</file>
|
||||
<file>icons/Manipulator_workbench_icon.svg</file>
|
||||
<file>icons/PartOMagic_workbench_icon.svg</file>
|
||||
<file>icons/Plot_workbench_icon.svg</file>
|
||||
<file>icons/Pyrate_workbench_icon.svg</file>
|
||||
<file>icons/Reporting_workbench_icon.svg</file>
|
||||
<file>icons/SheetMetal_workbench_icon.svg</file>
|
||||
<file>icons/Ship_workbench_icon.svg</file>
|
||||
<file>icons/Timber_workbench_icon.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -97,6 +97,17 @@ def urlopen(url):
|
||||
return u
|
||||
|
||||
|
||||
def getserver(url):
|
||||
|
||||
"""returns the server part of an url"""
|
||||
|
||||
if sys.version_info.major < 3:
|
||||
from urlparse import urlparse
|
||||
else:
|
||||
from urllib.parse import urlparse
|
||||
return '{uri.scheme}://{uri.netloc}/'.format(uri=urlparse(url))
|
||||
|
||||
|
||||
def update_macro_details(old_macro, new_macro):
|
||||
|
||||
"""Update a macro with information from another one
|
||||
|
||||
@@ -35,6 +35,7 @@ from addonmanager_macro import Macro
|
||||
from addonmanager_utilities import urlopen
|
||||
from addonmanager_utilities import translate
|
||||
from addonmanager_utilities import symlink
|
||||
from addonmanager_utilities import getserver
|
||||
|
||||
MACROS_BLACKLIST = ["BOLTS","WorkFeatures","how to install","PartsLibrary","FCGear"]
|
||||
OBSOLETE = ["assembly2","drawing_dimensioning","cura_engine"] # These addons will print an additional message informing the user
|
||||
@@ -382,12 +383,12 @@ class ShowWorker(QtCore.QThread):
|
||||
|
||||
self.info_label.emit( message )
|
||||
self.progressbar_show.emit(False)
|
||||
l = self.loadImages( message )
|
||||
l = self.loadImages( message, url )
|
||||
if l:
|
||||
self.info_label.emit( l )
|
||||
self.stop = True
|
||||
|
||||
def loadImages(self,message):
|
||||
def loadImages(self,message,url):
|
||||
|
||||
"checks if the given page contains images and downloads them"
|
||||
|
||||
@@ -402,6 +403,11 @@ class ShowWorker(QtCore.QThread):
|
||||
if not os.path.exists(store):
|
||||
os.makedirs(store)
|
||||
for path in imagepaths:
|
||||
if "?" in path:
|
||||
# remove everything after the ?
|
||||
path = path.split("?")[0]
|
||||
if not path.startswith("http"):
|
||||
path = getserver(url) + path
|
||||
name = path.split("/")[-1]
|
||||
if name and path.startswith("http"):
|
||||
storename = os.path.join(store,name)
|
||||
@@ -426,7 +432,7 @@ class ShowWorker(QtCore.QThread):
|
||||
pix = pix.fromImage(img.scaled(300,300,QtCore.Qt.KeepAspectRatio,QtCore.Qt.FastTransformation))
|
||||
pix.save(storename, "jpeg",100)
|
||||
|
||||
message = message.replace(path,"file://"+storename.replace("\\","/"))
|
||||
message = message.replace(path,"file:///"+storename.replace("\\","/"))
|
||||
return message
|
||||
return None
|
||||
|
||||
@@ -547,7 +553,7 @@ class InstallWorker(QtCore.QThread):
|
||||
try:
|
||||
answer = repo.pull()
|
||||
except:
|
||||
print("Error updating module",repos[idx][1]," - Please fix manually")
|
||||
print("Error updating module",self.repos[idx][1]," - Please fix manually")
|
||||
answer = repo.status()
|
||||
print(answer)
|
||||
else:
|
||||
|
||||
@@ -58,6 +58,15 @@ class _Fence(ArchComponent.Component):
|
||||
|
||||
self.Type = "Fence"
|
||||
|
||||
def __getstate__(self):
|
||||
return (self.sectionFaceNumbers)
|
||||
|
||||
def __setstate__(self, state):
|
||||
if state is not None and isinstance(state, tuple):
|
||||
self.sectionFaceNumbers = state[0]
|
||||
|
||||
return None
|
||||
|
||||
def execute(self, obj):
|
||||
import Part
|
||||
|
||||
@@ -97,7 +106,7 @@ class _Fence(ArchComponent.Component):
|
||||
obj, pathwire, downRotation)
|
||||
|
||||
postShapes = self.calculatePosts(obj, postPlacements)
|
||||
sectionShapes = self.calculateSections(
|
||||
sectionShapes, sectionFaceNumbers = self.calculateSections(
|
||||
obj, postPlacements, postLength, sectionLength)
|
||||
|
||||
allShapes = []
|
||||
@@ -106,6 +115,8 @@ class _Fence(ArchComponent.Component):
|
||||
|
||||
compound = Part.makeCompound(allShapes)
|
||||
|
||||
self.sectionFaceNumbers = sectionFaceNumbers
|
||||
|
||||
self.applyShape(obj, compound, obj.Placement,
|
||||
allowinvalid=True, allownosolid=True)
|
||||
|
||||
@@ -146,6 +157,11 @@ class _Fence(ArchComponent.Component):
|
||||
|
||||
shapes = []
|
||||
|
||||
# For the colorization algorithm we have to store the number of faces for each section
|
||||
# It is possible that a section is clipped. Then the number of faces is not equals to the
|
||||
# number of faces in the original section
|
||||
faceNumbers = []
|
||||
|
||||
for i in range(obj.NumberOfSections):
|
||||
startPlacement = postPlacements[i]
|
||||
endPlacement = postPlacements[i + 1]
|
||||
@@ -175,8 +191,9 @@ class _Fence(ArchComponent.Component):
|
||||
sectionCopy.Placement = placement
|
||||
|
||||
shapes.append(sectionCopy)
|
||||
faceNumbers.append(len(sectionCopy.Faces))
|
||||
|
||||
return shapes
|
||||
return (shapes, faceNumbers)
|
||||
|
||||
def clipSection(self, shape, length, clipLength):
|
||||
import Part
|
||||
@@ -189,14 +206,12 @@ class _Fence(ArchComponent.Component):
|
||||
FreeCAD.Vector(boundBox.XMin, boundBox.YMin, boundBox.ZMin))
|
||||
rightBox = Part.makeBox(halfLengthToCut, boundBox.YMax + 1, boundBox.ZMax + 1,
|
||||
FreeCAD.Vector(boundBox.XMin + halfLengthToCut + clipLength, boundBox.YMin, boundBox.ZMin))
|
||||
|
||||
|
||||
newShape = shape.cut([leftBox, rightBox])
|
||||
newBoundBox = newShape.BoundBox
|
||||
|
||||
newShape.translate(FreeCAD.Vector(-newBoundBox.XMin, 0, 0))
|
||||
|
||||
print(newShape.BoundBox)
|
||||
|
||||
return newShape.removeSplitter()
|
||||
|
||||
def calculatePathWire(self, obj):
|
||||
@@ -214,6 +229,17 @@ class _ViewProviderFence(ArchComponent.ViewProviderComponent):
|
||||
|
||||
def __init__(self, vobj):
|
||||
ArchComponent.ViewProviderComponent.__init__(self, vobj)
|
||||
self.setProperties(vobj)
|
||||
|
||||
def setProperties(self, vobj):
|
||||
pl = vobj.PropertiesList
|
||||
|
||||
if not "UseOriginalColors" in pl:
|
||||
vobj.addProperty("App::PropertyBool", "UseOriginalColors", "Fence", QT_TRANSLATE_NOOP(
|
||||
"App::Property", "When true, the fence will be colored like the original post and section."))
|
||||
|
||||
def onDocumentRestored(self, vobj):
|
||||
self.setProperties(vobj)
|
||||
|
||||
def getIcon(self):
|
||||
import Arch_rc
|
||||
@@ -234,6 +260,93 @@ class _ViewProviderFence(ArchComponent.ViewProviderComponent):
|
||||
|
||||
return children
|
||||
|
||||
def updateData(self, obj, prop):
|
||||
colorProps = ["Shape", "Section", "Post", "Path"]
|
||||
|
||||
if prop in colorProps:
|
||||
self.applyColors(obj)
|
||||
else:
|
||||
super().updateData(obj, prop)
|
||||
|
||||
def onChanged(self, vobj, prop):
|
||||
if prop == "UseOriginalColors":
|
||||
self.applyColors(vobj.Object)
|
||||
else:
|
||||
super().onChanged(vobj, prop)
|
||||
|
||||
def applyColors(self, obj):
|
||||
if not hasattr(obj.ViewObject, "UseOriginalColors") or not obj.ViewObject.UseOriginalColors:
|
||||
obj.ViewObject.DiffuseColor = [obj.ViewObject.ShapeColor]
|
||||
else:
|
||||
post = obj.Post
|
||||
section = obj.Section
|
||||
|
||||
numberOfPostFaces = len(post.Shape.Faces)
|
||||
numberOfSectionFaces = len(section.Shape.Faces)
|
||||
|
||||
if hasattr(obj.Proxy, 'sectionFaceNumbers'):
|
||||
sectionFaceNumbers = obj.Proxy.sectionFaceNumbers
|
||||
else:
|
||||
sectionFaceNumbers = [0]
|
||||
|
||||
if numberOfPostFaces == 0 or sum(sectionFaceNumbers) == 0:
|
||||
return
|
||||
|
||||
postColors = self.normalizeColors(post, numberOfPostFaces)
|
||||
defaultSectionColors = self.normalizeColors(
|
||||
section, numberOfSectionFaces)
|
||||
|
||||
ownColors = []
|
||||
|
||||
# At first all posts are added to the shape
|
||||
for i in range(obj.NumberOfPosts):
|
||||
ownColors.extend(postColors)
|
||||
|
||||
# Next all sections are added
|
||||
for i in range(obj.NumberOfSections):
|
||||
actualSectionFaceCount = sectionFaceNumbers[i]
|
||||
|
||||
if actualSectionFaceCount == numberOfSectionFaces:
|
||||
ownColors.extend(defaultSectionColors)
|
||||
else:
|
||||
ownColors.extend(self.normalizeColors(
|
||||
section, actualSectionFaceCount))
|
||||
|
||||
viewObject = obj.ViewObject
|
||||
viewObject.DiffuseColor = ownColors
|
||||
|
||||
def normalizeColors(self, obj, numberOfFaces):
|
||||
colors = obj.ViewObject.DiffuseColor
|
||||
|
||||
if obj.TypeId == 'PartDesign::Body':
|
||||
# When colorizing a PartDesign Body we have two options
|
||||
# 1. The whole body got a shape color, that means the tip has only a single diffuse color set
|
||||
# so we use the shape color of the body
|
||||
# 2. "Set colors" was called on the tip and the individual faces where colorized.
|
||||
# We use the diffuseColors of the tip in that case
|
||||
tipColors = obj.Tip.ViewObject.DiffuseColor
|
||||
|
||||
if len(tipColors) > 1:
|
||||
colors = tipColors
|
||||
|
||||
numberOfColors = len(colors)
|
||||
|
||||
if numberOfColors == 1:
|
||||
return colors * numberOfFaces
|
||||
|
||||
colorsToUse = colors.copy()
|
||||
|
||||
if numberOfColors == numberOfFaces:
|
||||
return colorsToUse
|
||||
else:
|
||||
# It is possible, that we have less faces than colors when something got clipped.
|
||||
# Remove the unneeded colors at the beginning and end
|
||||
halfNumberOfFacesToRemove = (numberOfColors - numberOfFaces) / 2
|
||||
start = int(math.ceil(halfNumberOfFacesToRemove))
|
||||
end = start + numberOfFaces
|
||||
|
||||
return colorsToUse[start:end]
|
||||
|
||||
|
||||
class _CommandFence:
|
||||
"the Arch Fence command definition"
|
||||
@@ -330,12 +443,30 @@ if __name__ == '__main__':
|
||||
def buildPost():
|
||||
post = Part.makeBox(100, 100, 1000, FreeCAD.Vector(0, 0, 0))
|
||||
|
||||
Part.show(post, "Post")
|
||||
Part.show(post, 'Post')
|
||||
|
||||
return FreeCAD.ActiveDocument.getObject('Post')
|
||||
|
||||
def colorizeFaces(o, color=(0.6, 0.0, 0.0, 0.0), faceIndizes=[2]):
|
||||
numberOfFaces = len(o.Shape.Faces)
|
||||
vo = o.ViewObject
|
||||
|
||||
originalColors = vo.DiffuseColor
|
||||
|
||||
if len(originalColors) == 1:
|
||||
newColors = originalColors * numberOfFaces
|
||||
else:
|
||||
newColors = originalColors.copy()
|
||||
|
||||
for i in faceIndizes:
|
||||
newColors[i] = color
|
||||
|
||||
vo.DiffuseColor = newColors
|
||||
|
||||
section = buildSection()
|
||||
path = buildPath()
|
||||
post = buildPost()
|
||||
|
||||
colorizeFaces(post)
|
||||
|
||||
print(makeFence(section, post, path))
|
||||
|
||||
@@ -45,6 +45,7 @@ def getIfcProduct(IfcType):
|
||||
name = "IfcBuildingElementProxy"
|
||||
if name in ArchIFCSchema.IfcProducts:
|
||||
return ArchIFCSchema.IfcProducts[name]
|
||||
return None
|
||||
|
||||
def getIfcProductAttribute(ifcProduct, name):
|
||||
|
||||
@@ -81,6 +82,8 @@ def addIfcProductAttribute(obj, attribute):
|
||||
|
||||
"Adds a given attribute property"
|
||||
|
||||
if not hasattr(obj,"IfcData"):
|
||||
return
|
||||
IfcData = obj.IfcData
|
||||
if "attributes" not in IfcData:
|
||||
IfcData["attributes"] = "{}"
|
||||
|
||||
@@ -189,7 +189,10 @@ def read(filename):
|
||||
|
||||
def export(exportList,filename,tessellation=1,colors=None):
|
||||
|
||||
"called when freecad exports a file"
|
||||
"""export(exportList,filename,tessellation=1,colors=None) -- exports FreeCAD contents to a DAE file.
|
||||
colors is an optional dictionary of objName:shapeColorTuple or objName:diffuseColorList elements
|
||||
to be used in non-GUI mode if you want to be able to export colors. Tessellation is used when breaking
|
||||
curved surfaces into triangles."""
|
||||
|
||||
if not checkCollada(): return
|
||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
|
||||
|
||||
@@ -1466,7 +1466,9 @@ class recycler:
|
||||
|
||||
def export(exportList,filename,colors=None):
|
||||
|
||||
"exports FreeCAD contents to an IFC file"
|
||||
"""export(exportList,filename,colors=None) -- exports FreeCAD contents to an IFC file.
|
||||
colors is an optional dictionary of objName:shapeColorTuple or objName:diffuseColorList elements
|
||||
to be used in non-GUI mode if you want to be able to export colors."""
|
||||
|
||||
getPreferences()
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ def export(exportList,filename,colors=None):
|
||||
outfile = pythonopen(filenamemtl,"w")
|
||||
outfile.write("# FreeCAD v" + ver[0] + "." + ver[1] + " build" + ver[2] + " Arch module\n")
|
||||
outfile.write("# http://www.freecadweb.org\n")
|
||||
kinds = {"AmbientColor":"Ka ","DiffuseColor":"Kd ","SpecularColor":"Ks ","EmissiveColor":"Ke ","Transparency":"d "}
|
||||
kinds = {"AmbientColor":"Ka ","DiffuseColor":"Kd ","SpecularColor":"Ks ","EmissiveColor":"Ke ","Transparency":"Tr "}
|
||||
done = [] # store names to avoid duplicates
|
||||
for mat in materials:
|
||||
if isinstance(mat,tuple):
|
||||
|
||||
@@ -218,6 +218,8 @@ App::DocumentObjectExecReturn *Pad::execute(void)
|
||||
TopExp_Explorer Ex(supportface,TopAbs_WIRE);
|
||||
if (!Ex.More())
|
||||
supportface = TopoDS_Face();
|
||||
|
||||
#if 0
|
||||
BRepFeat_MakePrism PrismMaker;
|
||||
PrismMaker.Init(base, sketchshape, supportface, dir, 2, 1);
|
||||
PrismMaker.Perform(upToFace);
|
||||
@@ -225,6 +227,9 @@ App::DocumentObjectExecReturn *Pad::execute(void)
|
||||
if (!PrismMaker.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Pad: Up to face: Could not extrude the sketch!");
|
||||
prism = PrismMaker.Shape();
|
||||
#else
|
||||
generatePrism(prism, method, base, sketchshape, supportface, upToFace, dir, 2, 1);
|
||||
#endif
|
||||
base.Nullify();
|
||||
} else {
|
||||
// A support object is always required and we need to use BRepFeat_MakePrism
|
||||
@@ -239,6 +244,7 @@ App::DocumentObjectExecReturn *Pad::execute(void)
|
||||
TopExp_Explorer Ex(supportface,TopAbs_WIRE);
|
||||
if (!Ex.More())
|
||||
supportface = TopoDS_Face();
|
||||
#if 0
|
||||
BRepFeat_MakePrism PrismMaker;
|
||||
PrismMaker.Init(base, sketchshape, supportface, dir, 2, 1);
|
||||
PrismMaker.Perform(upToFace);
|
||||
@@ -246,6 +252,9 @@ App::DocumentObjectExecReturn *Pad::execute(void)
|
||||
if (!PrismMaker.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Pad: Up to face: Could not extrude the sketch!");
|
||||
prism = PrismMaker.Shape();
|
||||
#else
|
||||
generatePrism(prism, method, base, sketchshape, supportface, upToFace, dir, 2, 1);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
generatePrism(prism, sketchshape, method, dir, L, L2,
|
||||
|
||||
@@ -174,6 +174,7 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
|
||||
TopExp_Explorer Ex(supportface,TopAbs_WIRE);
|
||||
if (!Ex.More())
|
||||
supportface = TopoDS_Face();
|
||||
#if 0
|
||||
BRepFeat_MakePrism PrismMaker;
|
||||
PrismMaker.Init(base, profileshape, supportface, dir, 0, 1);
|
||||
PrismMaker.Perform(upToFace);
|
||||
@@ -181,6 +182,10 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
|
||||
if (!PrismMaker.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Pocket: Up to face: Could not extrude the sketch!");
|
||||
TopoDS_Shape prism = PrismMaker.Shape();
|
||||
#else
|
||||
TopoDS_Shape prism;
|
||||
generatePrism(prism, method, base, profileshape, supportface, upToFace, dir, 0, 1);
|
||||
#endif
|
||||
|
||||
// And the really expensive way to get the SubShape...
|
||||
BRepAlgoAPI_Cut mkCut(base, prism);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <BRepExtrema_DistShapeShape.hxx>
|
||||
# include <BRepPrimAPI_MakePrism.hxx>
|
||||
# include <BRepFeat_MakePrism.hxx>
|
||||
# include <BRepProj_Projection.hxx>
|
||||
# include <Geom_Plane.hxx>
|
||||
# include <TopoDS.hxx>
|
||||
@@ -544,6 +545,35 @@ void ProfileBased::generatePrism(TopoDS_Shape& prism,
|
||||
|
||||
}
|
||||
|
||||
void ProfileBased::generatePrism(TopoDS_Shape& prism,
|
||||
const std::string& method,
|
||||
const TopoDS_Shape& baseshape,
|
||||
const TopoDS_Shape& profileshape,
|
||||
const TopoDS_Face& sketchface,
|
||||
const TopoDS_Face& uptoface,
|
||||
const gp_Dir& direction,
|
||||
Standard_Integer Mode,
|
||||
Standard_Boolean Modify)
|
||||
{
|
||||
if (method == "UpToFirst" || method == "UpToFace") {
|
||||
BRepFeat_MakePrism PrismMaker;
|
||||
TopoDS_Shape base = baseshape;
|
||||
TopoDS_Face supportface = sketchface;
|
||||
for (TopExp_Explorer xp(profileshape, TopAbs_FACE); xp.More(); xp.Next()) {
|
||||
PrismMaker.Init(base, xp.Current(), supportface, direction, Mode, Modify);
|
||||
PrismMaker.Perform(uptoface);
|
||||
if (!PrismMaker.IsDone())
|
||||
throw Base::RuntimeError("ProfileBased: Up to face: Could not extrude the sketch!");
|
||||
|
||||
base = PrismMaker.Shape();
|
||||
if (Mode == 2)
|
||||
Mode = 1;
|
||||
}
|
||||
|
||||
prism = base;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProfileBased::checkWireInsideFace(const TopoDS_Wire& wire, const TopoDS_Face& face,
|
||||
const gp_Dir& dir) {
|
||||
// Project wire onto the face (face, not surface! So limits of face apply)
|
||||
|
||||
@@ -134,6 +134,19 @@ protected:
|
||||
const double L2,
|
||||
const bool midplane,
|
||||
const bool reversed);
|
||||
/**
|
||||
* Generate a linear prism
|
||||
* It will be a stand-alone solid created with BRepFeat_MakePrism
|
||||
*/
|
||||
static void generatePrism(TopoDS_Shape& prism,
|
||||
const std::string& method,
|
||||
const TopoDS_Shape& baseshape,
|
||||
const TopoDS_Shape& profileshape,
|
||||
const TopoDS_Face& sketchface,
|
||||
const TopoDS_Face& uptoface,
|
||||
const gp_Dir& direction,
|
||||
Standard_Integer Mode,
|
||||
Standard_Boolean Modify);
|
||||
|
||||
/// Check whether the wire after projection on the face is inside the face
|
||||
static bool checkWireInsideFace(const TopoDS_Wire& wire,
|
||||
|
||||
Reference in New Issue
Block a user