Merge branch 'master' of ssh://git.code.sf.net/p/free-cad/code
This commit is contained in:
commit
d99a09b03c
|
@ -97,6 +97,9 @@ class _CommandStructure:
|
|||
import DraftTrackers
|
||||
self.points = []
|
||||
self.tracker = DraftTrackers.boxTracker()
|
||||
self.tracker.width(self.Width)
|
||||
self.tracker.height(self.Height)
|
||||
self.tracker.length(self.Length)
|
||||
self.tracker.on()
|
||||
FreeCADGui.Snapper.getPoint(callback=self.getPoint,movecallback=self.update,extradlg=self.taskbox())
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ class _CommandWall:
|
|||
self.Width = 0.1
|
||||
self.Height = 1
|
||||
self.Align = "Center"
|
||||
self.Length = None
|
||||
self.continueCmd = False
|
||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
|
||||
self.JOIN_WALLS = p.GetBool("joinWallSketches")
|
||||
|
@ -223,12 +224,24 @@ class _CommandWall:
|
|||
else:
|
||||
dv = DraftVecUtils.neg(dv)
|
||||
self.tracker.update([b.add(dv),point.add(dv)])
|
||||
if self.Length:
|
||||
self.Length.setValue(bv.Length)
|
||||
|
||||
def taskbox(self):
|
||||
"sets up a taskbox widget"
|
||||
w = QtGui.QWidget()
|
||||
w.setWindowTitle(str(translate("Arch","Wall options")))
|
||||
lay0 = QtGui.QVBoxLayout(w)
|
||||
|
||||
lay5 = QtGui.QHBoxLayout()
|
||||
lay0.addLayout(lay5)
|
||||
label5 = QtGui.QLabel(str(translate("Arch","Length")))
|
||||
lay5.addWidget(label5)
|
||||
self.Length = QtGui.QDoubleSpinBox()
|
||||
self.Length.setDecimals(2)
|
||||
self.Length.setValue(0.00)
|
||||
lay5.addWidget(self.Length)
|
||||
|
||||
lay1 = QtGui.QHBoxLayout()
|
||||
lay0.addLayout(lay1)
|
||||
label1 = QtGui.QLabel(str(translate("Arch","Width")))
|
||||
|
@ -237,6 +250,7 @@ class _CommandWall:
|
|||
value1.setDecimals(2)
|
||||
value1.setValue(self.Width)
|
||||
lay1.addWidget(value1)
|
||||
|
||||
lay2 = QtGui.QHBoxLayout()
|
||||
lay0.addLayout(lay2)
|
||||
label2 = QtGui.QLabel(str(translate("Arch","Height")))
|
||||
|
@ -245,6 +259,7 @@ class _CommandWall:
|
|||
value2.setDecimals(2)
|
||||
value2.setValue(self.Height)
|
||||
lay2.addWidget(value2)
|
||||
|
||||
lay3 = QtGui.QHBoxLayout()
|
||||
lay0.addLayout(lay3)
|
||||
label3 = QtGui.QLabel(str(translate("Arch","Alignment")))
|
||||
|
@ -254,6 +269,7 @@ class _CommandWall:
|
|||
value3.addItems(items)
|
||||
value3.setCurrentIndex(items.index(self.Align))
|
||||
lay3.addWidget(value3)
|
||||
|
||||
value4 = QtGui.QCheckBox(str(translate("Arch","Continue")))
|
||||
lay0.addWidget(value4)
|
||||
QtCore.QObject.connect(value1,QtCore.SIGNAL("valueChanged(double)"),self.setWidth)
|
||||
|
|
|
@ -59,13 +59,14 @@ class ArchWorkbench(Workbench):
|
|||
" *@!!!!!$=* ",
|
||||
" =>!!$& ",
|
||||
" -+ ",
|
||||
" "};"""
|
||||
" "};"""
|
||||
|
||||
MenuText = "Arch"
|
||||
ToolTip = "Architecture workbench"
|
||||
|
||||
|
||||
def Initialize(self):
|
||||
import DraftTools,DraftGui,Arch_rc,Arch,Draft_rc
|
||||
from DraftTools import translate
|
||||
|
||||
# arch tools
|
||||
self.archtools = ["Arch_Wall","Arch_Structure",
|
||||
|
@ -91,23 +92,24 @@ class ArchWorkbench(Workbench):
|
|||
"Draft_ShowSnapBar","Draft_ToggleGrid","Draft_UndoLine",
|
||||
"Draft_FinishLine","Draft_CloseLine"]
|
||||
|
||||
self.appendToolbar(str(DraftTools.translate("arch","Arch tools")),self.archtools)
|
||||
self.appendToolbar(str(DraftTools.translate("arch","Draft tools")),self.drafttools)
|
||||
self.appendToolbar(str(DraftTools.translate("arch","Draft mod tools")),self.draftmodtools)
|
||||
self.appendMenu([str(DraftTools.translate("arch","&Architecture")),str(DraftTools.translate("arch","Conversion Tools"))],self.meshtools)
|
||||
self.appendMenu([str(DraftTools.translate("arch","&Architecture")),str(DraftTools.translate("arch","Calculation Tools"))],self.calctools)
|
||||
self.appendMenu(str(DraftTools.translate("arch","&Architecture")),self.archtools)
|
||||
self.appendMenu(str(DraftTools.translate("arch","&Draft")),self.drafttools+self.draftmodtools)
|
||||
self.appendMenu([str(DraftTools.translate("arch","&Draft")),str(DraftTools.translate("arch","Context Tools"))],self.draftcontexttools)
|
||||
self.appendToolbar(str(translate("arch","Arch tools")),self.archtools)
|
||||
self.appendToolbar(str(translate("arch","Draft tools")),self.drafttools)
|
||||
self.appendToolbar(str(translate("arch","Draft mod tools")),self.draftmodtools)
|
||||
self.appendMenu([str(translate("arch","&Architecture")),str(translate("arch","Conversion Tools"))],self.meshtools)
|
||||
self.appendMenu([str(translate("arch","&Architecture")),str(translate("arch","Calculation Tools"))],self.calctools)
|
||||
self.appendMenu(str(translate("arch","&Architecture")),self.archtools)
|
||||
self.appendMenu(str(translate("arch","&Draft")),self.drafttools+self.draftmodtools)
|
||||
self.appendMenu([str(translate("arch","&Draft")),str(translate("arch","Context Tools"))],self.draftcontexttools)
|
||||
FreeCADGui.addIconPath(":/icons")
|
||||
FreeCADGui.addLanguagePath(":/translations")
|
||||
FreeCADGui.addPreferencePage(":/ui/archprefs-base.ui","Arch")
|
||||
if not hasattr(FreeCADGui.draftToolBar,"loadedPreferences"):
|
||||
FreeCADGui.addPreferencePage(":/ui/userprefs-base.ui","Draft")
|
||||
FreeCADGui.addPreferencePage(":/ui/userprefs-import.ui","Draft")
|
||||
FreeCADGui.draftToolBar.loadedPreferences = True
|
||||
if hasattr(FreeCADGui,"draftToolBar"):
|
||||
if not hasattr(FreeCADGui.draftToolBar,"loadedPreferences"):
|
||||
FreeCADGui.addPreferencePage(":/ui/userprefs-base.ui","Draft")
|
||||
FreeCADGui.addPreferencePage(":/ui/userprefs-import.ui","Draft")
|
||||
FreeCADGui.draftToolBar.loadedPreferences = True
|
||||
Log ('Loading Arch module... done\n')
|
||||
|
||||
|
||||
def Activated(self):
|
||||
if hasattr(FreeCADGui,"draftToolBar"):
|
||||
FreeCADGui.draftToolBar.Activated()
|
||||
|
@ -121,7 +123,7 @@ class ArchWorkbench(Workbench):
|
|||
if hasattr(FreeCADGui,"Snapper"):
|
||||
FreeCADGui.Snapper.hide()
|
||||
Msg("Arch workbench deactivated\n")
|
||||
|
||||
|
||||
def ContextMenu(self, recipient):
|
||||
self.appendContextMenu("Draft context tools",self.draftcontexttools)
|
||||
|
||||
|
@ -129,9 +131,12 @@ class ArchWorkbench(Workbench):
|
|||
return "Gui::PythonWorkbench"
|
||||
|
||||
FreeCADGui.addWorkbench(ArchWorkbench)
|
||||
|
||||
# add import/export types
|
||||
FreeCAD.addImportType("Industry Foundation Classes (*.ifc)","importIFC")
|
||||
FreeCAD.addExportType("Wavefront OBJ - Arch module (*.obj)","importOBJ")
|
||||
FreeCAD.addExportType("WebGL file (*.html)","importWebGL")
|
||||
|
||||
# check for pycollada
|
||||
try:
|
||||
import collada
|
||||
|
|
|
@ -33,7 +33,7 @@ Report to Draft.py for info
|
|||
import FreeCAD, FreeCADGui, os, Draft, sys
|
||||
|
||||
try:
|
||||
from PyQt4 import QtCore,QtGui,QtSvg
|
||||
from PyQt4 import QtCore,QtGui,QtSvg
|
||||
except:
|
||||
FreeCAD.Console.PrintMessage("Error: Python-qt4 package must be installed on your system to use the Draft module.")
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ __url__ = "http://free-cad.sourceforge.net"
|
|||
|
||||
|
||||
import FreeCAD, FreeCADGui, math, Draft, DraftGui, DraftTrackers, DraftVecUtils
|
||||
from DraftGui import todo,getMainWindow
|
||||
from FreeCAD import Vector
|
||||
from pivy import coin
|
||||
from PyQt4 import QtCore,QtGui
|
||||
|
@ -72,11 +71,15 @@ class Snapper:
|
|||
self.constrainLine = None
|
||||
self.trackLine = None
|
||||
self.radiusTracker = None
|
||||
self.dim1 = None
|
||||
self.dim2 = None
|
||||
self.snapInfo = None
|
||||
self.lastSnappedObject = None
|
||||
self.lastArchPoint = None
|
||||
self.active = True
|
||||
self.forceGridOff = False
|
||||
self.trackers = [[],[],[],[],[]] # view, grid, snap, extline, radius
|
||||
# the trackers are stored in lists because there can be several views, each with its own set
|
||||
self.trackers = [[],[],[],[],[],[],[]] # view, grid, snap, extline, radius, dim1, dim2
|
||||
|
||||
self.polarAngles = [90,45]
|
||||
|
||||
|
@ -86,9 +89,9 @@ class Snapper:
|
|||
'parallel':'circle',
|
||||
'grid':'circle',
|
||||
'endpoint':'dot',
|
||||
'midpoint':'dot',
|
||||
'midpoint':'square',
|
||||
'perpendicular':'dot',
|
||||
'angle':'dot',
|
||||
'angle':'square',
|
||||
'center':'dot',
|
||||
'ortho':'dot',
|
||||
'intersection':'dot'}
|
||||
|
@ -118,7 +121,7 @@ class Snapper:
|
|||
|
||||
if not hasattr(self,"toolbar"):
|
||||
self.makeSnapToolBar()
|
||||
mw = getMainWindow()
|
||||
mw = DraftGui.getMainWindow()
|
||||
bt = mw.findChild(QtGui.QToolBar,"Draft Snap")
|
||||
if not bt:
|
||||
mw.addToolBar(self.toolbar)
|
||||
|
@ -173,6 +176,10 @@ class Snapper:
|
|||
self.extLine.off()
|
||||
if self.trackLine:
|
||||
self.trackLine.off()
|
||||
if self.dim1:
|
||||
self.dim1.off()
|
||||
if self.dim2:
|
||||
self.dim2.off()
|
||||
|
||||
point = self.getApparentPoint(screenpos[0],screenpos[1])
|
||||
|
||||
|
@ -200,6 +207,9 @@ class Snapper:
|
|||
if self.trackLine and lastpoint and (not noTracker):
|
||||
self.trackLine.p2(fp)
|
||||
self.trackLine.on()
|
||||
# set the arch point tracking
|
||||
if self.lastArchPoint:
|
||||
self.setArchDims(self.lastArchPoint,fp)
|
||||
return fp
|
||||
|
||||
else:
|
||||
|
@ -232,6 +242,7 @@ class Snapper:
|
|||
comp = self.snapInfo['Component']
|
||||
|
||||
if (Draft.getType(obj) == "Wall") and not oldActive:
|
||||
# special snapping for wall: only to its base shape (except when CTRL is pressed)
|
||||
edges = []
|
||||
for o in [obj]+obj.Additions:
|
||||
if Draft.getType(o) == "Wall":
|
||||
|
@ -243,7 +254,20 @@ class Snapper:
|
|||
snaps.extend(self.snapToPerpendicular(edge,lastpoint))
|
||||
snaps.extend(self.snapToIntersection(edge))
|
||||
snaps.extend(self.snapToElines(edge,eline))
|
||||
|
||||
|
||||
elif (Draft.getType(obj) == "Structure") and not oldActive:
|
||||
# special snapping for struct: only to its base point (except when CTRL is pressed)
|
||||
if obj.Base:
|
||||
for edge in o.Base.Shape.Edges:
|
||||
snaps.extend(self.snapToEndpoints(edge))
|
||||
snaps.extend(self.snapToMidpoint(edge))
|
||||
snaps.extend(self.snapToPerpendicular(edge,lastpoint))
|
||||
snaps.extend(self.snapToIntersection(edge))
|
||||
snaps.extend(self.snapToElines(edge,eline))
|
||||
else:
|
||||
b = obj.Placement.Base
|
||||
snaps.append([b,'endpoint',b])
|
||||
|
||||
elif obj.isDerivedFrom("Part::Feature"):
|
||||
if (not self.maxEdges) or (len(obj.Edges) <= self.maxEdges):
|
||||
if "Edge" in comp:
|
||||
|
@ -327,7 +351,15 @@ class Snapper:
|
|||
self.trackLine.on()
|
||||
# set the cursor
|
||||
self.setCursor(winner[1])
|
||||
|
||||
|
||||
# set the arch point tracking
|
||||
if self.lastArchPoint:
|
||||
self.setArchDims(self.lastArchPoint,fp)
|
||||
if Draft.getType(obj) in ["Wall","Structure"]:
|
||||
self.lastArchPoint = winner[2]
|
||||
else:
|
||||
self.lastArchPoint = None
|
||||
|
||||
# return the final point
|
||||
return fp
|
||||
|
||||
|
@ -644,6 +676,21 @@ class Snapper:
|
|||
nv = DraftVecUtils.project(dv,DraftGeomUtils.vec(edge))
|
||||
np = (edge.Vertexes[0].Point).add(nv)
|
||||
return np
|
||||
|
||||
def setArchDims(self,p1,p2):
|
||||
"show arch dimensions between 2 points"
|
||||
if not self.dim1:
|
||||
self.dim1 = DraftTrackers.archDimTracker(mode=2)
|
||||
if not self.dim2:
|
||||
self.dim1 = DraftTrackers.archDimTracker(mode=3)
|
||||
self.dim1.p1(p1)
|
||||
self.dim2.p1(p1)
|
||||
self.dim1.p2(p2)
|
||||
self.dim2.p2(p2)
|
||||
if self.dim1.Distance:
|
||||
self.dim1.on()
|
||||
if self.dim2.Distance:
|
||||
self.dim2.on()
|
||||
|
||||
def setCursor(self,mode=None):
|
||||
"setCursor(self,mode=None): sets or resets the cursor to the given mode or resets"
|
||||
|
@ -687,6 +734,10 @@ class Snapper:
|
|||
self.extLine.off()
|
||||
if self.radiusTracker:
|
||||
self.radiusTracker.off()
|
||||
if self.dim1:
|
||||
self.dim1.off()
|
||||
if self.dim2:
|
||||
self.dim2.off()
|
||||
if self.grid:
|
||||
if not Draft.getParam("alwaysShowGrid"):
|
||||
self.grid.off()
|
||||
|
@ -696,6 +747,7 @@ class Snapper:
|
|||
if Draft.getParam("hideSnapBar"):
|
||||
self.toolbar.hide()
|
||||
self.mask = None
|
||||
self.lastArchPoint = None
|
||||
|
||||
def constrain(self,point,basepoint=None,axis=None):
|
||||
'''constrain(point,basepoint=None,axis=None: Returns a
|
||||
|
@ -929,7 +981,7 @@ class Snapper:
|
|||
"shows the toolbar and the grid"
|
||||
if not hasattr(self,"toolbar"):
|
||||
self.makeSnapToolBar()
|
||||
mw = getMainWindow()
|
||||
mw = DraftGui.getMainWindow()
|
||||
bt = mw.findChild(QtGui.QToolBar,"Draft Snap")
|
||||
if not bt:
|
||||
mw.addToolBar(self.toolbar)
|
||||
|
@ -959,6 +1011,8 @@ class Snapper:
|
|||
self.tracker = self.trackers[2][i]
|
||||
self.extLine = self.trackers[3][i]
|
||||
self.radiusTracker = self.trackers[4][i]
|
||||
self.dim1 = self.trackers[5][i]
|
||||
self.dim2 = self.trackers[6][i]
|
||||
else:
|
||||
if Draft.getParam("grid"):
|
||||
self.grid = DraftTrackers.gridTracker()
|
||||
|
@ -967,11 +1021,15 @@ class Snapper:
|
|||
self.tracker = DraftTrackers.snapTracker()
|
||||
self.extLine = DraftTrackers.lineTracker(dotted=True)
|
||||
self.radiusTracker = DraftTrackers.radiusTracker()
|
||||
self.dim1 = DraftTrackers.archDimTracker(mode=2)
|
||||
self.dim2 = DraftTrackers.archDimTracker(mode=3)
|
||||
self.trackers[0].append(v)
|
||||
self.trackers[1].append(self.grid)
|
||||
self.trackers[2].append(self.tracker)
|
||||
self.trackers[3].append(self.extLine)
|
||||
self.trackers[4].append(self.radiusTracker)
|
||||
self.trackers[5].append(self.dim1)
|
||||
self.trackers[6].append(self.dim2)
|
||||
if self.grid and (not self.forceGridOff):
|
||||
self.grid.set()
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ __url__ = "http://free-cad.sourceforge.net"
|
|||
import FreeCAD,FreeCADGui,math,Draft, DraftVecUtils
|
||||
from FreeCAD import Vector
|
||||
from pivy import coin
|
||||
from DraftGui import todo
|
||||
|
||||
class Tracker:
|
||||
"A generic Draft Tracker, to be used by other specific trackers"
|
||||
|
@ -52,9 +51,11 @@ class Tracker:
|
|||
self.switch.addChild(node)
|
||||
self.switch.whichChild = -1
|
||||
self.Visible = False
|
||||
from DraftGui import todo
|
||||
todo.delay(self._insertSwitch, self.switch)
|
||||
|
||||
def finalize(self):
|
||||
from DraftGui import todo
|
||||
todo.delay(self._removeSwitch, self.switch)
|
||||
self.switch = None
|
||||
|
||||
|
@ -783,3 +784,57 @@ class radiusTracker(Tracker):
|
|||
self.trans.translation.setValue([arg2.x,arg2.y,arg2.z])
|
||||
else:
|
||||
self.sphere.radius.setValue(arg2)
|
||||
|
||||
class archDimTracker(Tracker):
|
||||
"A wrapper around a Sketcher dim"
|
||||
def __init__(self,p1=FreeCAD.Vector(0,0,0),p2=FreeCAD.Vector(1,0,0),mode=1):
|
||||
import SketcherGui
|
||||
self.dimnode = coin.SoType.fromName("SoDatumLabel").createInstance()
|
||||
p1node = coin.SbVec3f([p1.x,p1.y,p1.z])
|
||||
p2node = coin.SbVec3f([p2.x,p2.y,p2.z])
|
||||
self.dimnode.pnts.setValues([p1node,p2node])
|
||||
self.dimnode.lineWidth = 1
|
||||
color = FreeCADGui.draftToolBar.getDefaultColor("snap")
|
||||
self.dimnode.textColor.setValue(coin.SbVec3f(color))
|
||||
self.setString()
|
||||
self.setMode(mode)
|
||||
Tracker.__init__(self,children=[self.dimnode])
|
||||
|
||||
def setString(self,text=None):
|
||||
"sets the dim string to the given value or auto value"
|
||||
self.dimnode.param1.setValue(.5)
|
||||
p1 = Vector(self.dimnode.pnts.getValues()[0].getValue())
|
||||
p2 = Vector(self.dimnode.pnts.getValues()[-1].getValue())
|
||||
m = self.dimnode.datumtype.getValue()
|
||||
if m == 2:
|
||||
self.Distance = (DraftVecUtils.project(p2.sub(p1),Vector(1,0,0))).Length
|
||||
elif m == 3:
|
||||
self.Distance = (DraftVecUtils.project(p2.sub(p1),Vector(0,1,0))).Length
|
||||
else:
|
||||
self.Distance = (p2.sub(p1)).Length
|
||||
if not text:
|
||||
text = Draft.getParam("dimPrecision")
|
||||
text = "%."+str(text)+"f"
|
||||
text = (text % self.Distance)
|
||||
self.dimnode.string.setValue(text)
|
||||
|
||||
def setMode(self,mode=1):
|
||||
"""sets the mode: 0 = without lines (a simple mark), 1 =
|
||||
aligned (default), 2 = horizontal, 3 = vertical."""
|
||||
self.dimnode.datumtype.setValue(mode)
|
||||
|
||||
def p1(self,point=None):
|
||||
"sets or gets the first point of the dim"
|
||||
if point:
|
||||
self.dimnode.pnts.set1Value(0,point.x,point.y,point.z)
|
||||
self.setString()
|
||||
else:
|
||||
return Vector(self.dimnode.pnts.getValues()[0].getValue())
|
||||
|
||||
def p2(self,point=None):
|
||||
"sets or gets the second point of the dim"
|
||||
if point:
|
||||
self.dimnode.pnts.set1Value(1,point.x,point.y,point.z)
|
||||
self.setString()
|
||||
else:
|
||||
return Vector(self.dimnode.pnts.getValues()[-1].getValue())
|
||||
|
|
|
@ -62,8 +62,8 @@ class DraftWorkbench (Workbench):
|
|||
".&&.++***,,)))!!",
|
||||
"#==+)!!!!!!!!!!!",
|
||||
" ##+)!!!!!!!!!!!",
|
||||
" *,,,,,,,,,,,,"};"""
|
||||
|
||||
" *,,,,,,,,,,,,"};"""
|
||||
|
||||
MenuText = "Draft"
|
||||
ToolTip = "The Draft module is used for basic 2D CAD Drafting"
|
||||
|
||||
|
@ -92,19 +92,18 @@ class DraftWorkbench (Workbench):
|
|||
depsOK = True
|
||||
if not depsOK:
|
||||
return
|
||||
|
||||
|
||||
# import Draft tools, icons and macros menu
|
||||
try:
|
||||
import os,macros,DraftTools,DraftGui,Draft_rc
|
||||
import os,macros,Draft_rc,DraftTools, DraftGui
|
||||
from DraftTools import translate
|
||||
FreeCADGui.addLanguagePath(":/translations")
|
||||
FreeCADGui.addIconPath(":/icons")
|
||||
if not hasattr(FreeCADGui.draftToolBar,"loadedPreferences"):
|
||||
FreeCADGui.addPreferencePage(":/ui/userprefs-base.ui","Draft")
|
||||
FreeCADGui.addPreferencePage(":/ui/userprefs-import.ui","Draft")
|
||||
FreeCADGui.draftToolBar.loadedPreferences = True
|
||||
self.appendMenu(["&Macro",str(DraftTools.translate("draft","Installed Macros"))],macros.macrosList)
|
||||
Log ('Loading Draft module...done\n')
|
||||
self.appendMenu(["&Macro",str(translate("draft","Installed Macros"))],macros.macrosList)
|
||||
except:
|
||||
pass
|
||||
|
||||
# setup menus
|
||||
self.cmdList = ["Draft_Line","Draft_Wire","Draft_Circle","Draft_Arc","Draft_Ellipse",
|
||||
"Draft_Polygon","Draft_Rectangle", "Draft_Text",
|
||||
"Draft_Dimension", "Draft_BSpline","Draft_Point",
|
||||
|
@ -120,10 +119,16 @@ class DraftWorkbench (Workbench):
|
|||
self.lineList = ["Draft_UndoLine","Draft_FinishLine","Draft_CloseLine"]
|
||||
self.appendToolbar(QT_TRANSLATE_NOOP("Workbench","Draft creation tools"),self.cmdList)
|
||||
self.appendToolbar(QT_TRANSLATE_NOOP("Workbench","Draft modification tools"),self.modList)
|
||||
self.appendMenu(str(DraftTools.translate("draft","&Draft")),self.cmdList+self.modList)
|
||||
self.appendMenu([str(DraftTools.translate("draft","&Draft")),str(DraftTools.translate("draft","Context tools"))],self.treecmdList)
|
||||
self.appendMenu([str(DraftTools.translate("draft","&Draft")),str(DraftTools.translate("draft","Wire tools"))],self.lineList)
|
||||
|
||||
self.appendMenu(str(translate("draft","&Draft")),self.cmdList+self.modList)
|
||||
self.appendMenu([str(translate("draft","&Draft")),str(translate("draft","Context tools"))],self.treecmdList)
|
||||
self.appendMenu([str(translate("draft","&Draft")),str(translate("draft","Wire tools"))],self.lineList)
|
||||
if hasattr(FreeCADGui,"draftToolBar"):
|
||||
if not hasattr(FreeCADGui.draftToolBar,"loadedPreferences"):
|
||||
FreeCADGui.addPreferencePage(":/ui/userprefs-base.ui","Draft")
|
||||
FreeCADGui.addPreferencePage(":/ui/userprefs-import.ui","Draft")
|
||||
FreeCADGui.draftToolBar.loadedPreferences = True
|
||||
Log ('Loading Draft module...done\n')
|
||||
|
||||
def Activated(self):
|
||||
if hasattr(FreeCADGui,"draftToolBar"):
|
||||
FreeCADGui.draftToolBar.Activated()
|
||||
|
@ -159,6 +164,8 @@ class DraftWorkbench (Workbench):
|
|||
# ability to turn off the Draft workbench (since it is also all included in Arch)
|
||||
if not FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("hideDraftWorkbench"):
|
||||
FreeCADGui.addWorkbench(DraftWorkbench)
|
||||
|
||||
# add Import/Export types
|
||||
App.addImportType("Autodesk DXF (*.dxf)","importDXF")
|
||||
App.addImportType("SVG as geometry (*.svg)","importSVG")
|
||||
App.addImportType("Open CAD Format (*.oca *.gcad)","importOCA")
|
||||
|
@ -167,7 +174,7 @@ App.addExportType("Autodesk DXF (*.dxf)","importDXF")
|
|||
App.addExportType("Flattened SVG (*.svg)","importSVG")
|
||||
App.addExportType("Open CAD Format (*.oca)","importOCA")
|
||||
|
||||
# DWG support
|
||||
# add DWG support
|
||||
import importDWG
|
||||
if importDWG.getTeighaConverter():
|
||||
App.addImportType("Autodesk DWG (*.dwg)","importDWG")
|
||||
|
|
|
@ -38,7 +38,7 @@ currently unsupported: use, image
|
|||
# implement inherting fill style from group
|
||||
# handle relative units
|
||||
|
||||
import xml.sax, string, FreeCAD, os, math, re, Draft, DraftVecUtils, DraftGeomUtils
|
||||
import xml.sax, string, FreeCAD, os, math, re, Draft, DraftVecUtils
|
||||
from FreeCAD import Vector
|
||||
|
||||
try: import FreeCADGui
|
||||
|
@ -283,6 +283,7 @@ def makewire(path,checkclosed=False,donttry=False):
|
|||
#ToDo Do not catch all exceptions
|
||||
if not donttry:
|
||||
try:
|
||||
import DraftGeomUtils
|
||||
sh = Part.Wire(DraftGeomUtils.sortEdges(path))
|
||||
#sh = Part.Wire(path)
|
||||
isok = (not checkclosed) or sh.isClosed()
|
||||
|
|
|
@ -103,9 +103,13 @@ void PartExport initPart()
|
|||
App::GetApplication().addExportType("STEP with colors (*.step *.stp)","ImportGui");
|
||||
#endif
|
||||
#endif
|
||||
#if defined(FC_OS_LINUX)
|
||||
OSD::SetSignal();
|
||||
#endif
|
||||
// This is highly experimental and we should keep an eye on it
|
||||
// if we have mysterious crashes
|
||||
// The argument must be 'Standard_False' to avoid FPE caused by
|
||||
// Python's cmath module.
|
||||
//#if defined(FC_OS_LINUX)
|
||||
OSD::SetSignal(Standard_False);
|
||||
//#endif
|
||||
|
||||
PyObject* partModule = Py_InitModule3("Part", Part_methods, module_part_doc); /* mod name, table ptr */
|
||||
Base::Console().Log("Loading Part module... done\n");
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <Mod/Part/App/PropertyTopoShape.h>
|
||||
|
||||
#include "SoBrepShape.h"
|
||||
#include "SoBrepFaceSet.h"
|
||||
#include "SoFCShapeObject.h"
|
||||
#include "ViewProvider.h"
|
||||
#include "ViewProviderExt.h"
|
||||
|
|
|
@ -128,6 +128,8 @@ SET(PartGui_SRCS
|
|||
SoFCShapeObject.h
|
||||
SoBrepShape.cpp
|
||||
SoBrepShape.h
|
||||
SoBrepFaceSet.cpp
|
||||
SoBrepFaceSet.h
|
||||
ViewProvider.cpp
|
||||
ViewProvider.h
|
||||
ViewProviderExt.cpp
|
||||
|
|
987
src/Mod/Part/Gui/SoBrepFaceSet.cpp
Normal file
987
src/Mod/Part/Gui/SoBrepFaceSet.cpp
Normal file
|
@ -0,0 +1,987 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#if 0
|
||||
#ifndef _PreComp_
|
||||
# ifdef FC_OS_WIN32
|
||||
# include <windows.h>
|
||||
# endif
|
||||
# ifdef FC_OS_MACOSX
|
||||
# include <OpenGL/gl.h>
|
||||
# else
|
||||
# include <GL/gl.h>
|
||||
# endif
|
||||
# include <float.h>
|
||||
# include <algorithm>
|
||||
# include <Inventor/SoPickedPoint.h>
|
||||
# include <Inventor/SoPrimitiveVertex.h>
|
||||
# include <Inventor/actions/SoCallbackAction.h>
|
||||
# include <Inventor/actions/SoGetBoundingBoxAction.h>
|
||||
# include <Inventor/actions/SoGetPrimitiveCountAction.h>
|
||||
# include <Inventor/actions/SoGLRenderAction.h>
|
||||
# include <Inventor/actions/SoPickAction.h>
|
||||
# include <Inventor/actions/SoWriteAction.h>
|
||||
# include <Inventor/bundles/SoMaterialBundle.h>
|
||||
# include <Inventor/bundles/SoTextureCoordinateBundle.h>
|
||||
# include <Inventor/elements/SoOverrideElement.h>
|
||||
# include <Inventor/elements/SoCoordinateElement.h>
|
||||
# include <Inventor/elements/SoGLCoordinateElement.h>
|
||||
# include <Inventor/elements/SoGLCacheContextElement.h>
|
||||
# include <Inventor/elements/SoLineWidthElement.h>
|
||||
# include <Inventor/elements/SoPointSizeElement.h>
|
||||
# include <Inventor/errors/SoReadError.h>
|
||||
# include <Inventor/details/SoFaceDetail.h>
|
||||
# include <Inventor/details/SoLineDetail.h>
|
||||
# include <Inventor/misc/SoState.h>
|
||||
#endif
|
||||
|
||||
#include <Gui/SoFCUnifiedSelection.h>
|
||||
#include <Gui/SoFCSelectionAction.h>
|
||||
#include <Base/Console.h>
|
||||
|
||||
|
||||
#include "SoBrepFaceSet.h"
|
||||
|
||||
|
||||
using namespace PartGui;
|
||||
|
||||
|
||||
SO_NODE_SOURCE(SoBrepFaceSet);
|
||||
|
||||
void SoBrepFaceSet::initClass()
|
||||
{
|
||||
SO_NODE_INIT_CLASS(SoBrepFaceSet, SoIndexedFaceSet, "IndexedFaceSet");
|
||||
}
|
||||
|
||||
SoBrepFaceSet::SoBrepFaceSet()
|
||||
{
|
||||
SO_NODE_CONSTRUCTOR(SoBrepFaceSet);
|
||||
SO_NODE_ADD_FIELD(partIndex, (-1));
|
||||
SO_NODE_ADD_FIELD(highlightIndex, (-1));
|
||||
SO_NODE_ADD_FIELD(selectionIndex, (-1));
|
||||
selectionIndex.setNum(0);
|
||||
}
|
||||
|
||||
|
||||
SoBrepFaceSet::~SoBrepFaceSet()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SoBrepFaceSet::doAction(SoAction* action)
|
||||
{
|
||||
if (action->getTypeId() == Gui::SoHighlightElementAction::getClassTypeId()) {
|
||||
Gui::SoHighlightElementAction* hlaction = static_cast<Gui::SoHighlightElementAction*>(action);
|
||||
if (!hlaction->isHighlighted()) {
|
||||
this->highlightIndex = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
const SoDetail* detail = hlaction->getElement();
|
||||
if (detail) {
|
||||
if (detail->isOfType(SoFaceDetail::getClassTypeId())) {
|
||||
int index = static_cast<const SoFaceDetail*>(detail)->getPartIndex();
|
||||
this->highlightIndex.setValue(index);
|
||||
this->highlightColor = hlaction->getColor();
|
||||
}
|
||||
else {
|
||||
this->highlightIndex = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (action->getTypeId() == Gui::SoSelectionElementAction::getClassTypeId()) {
|
||||
Gui::SoSelectionElementAction* selaction = static_cast<Gui::SoSelectionElementAction*>(action);
|
||||
this->selectionColor = selaction->getColor();
|
||||
if (selaction->getType() == Gui::SoSelectionElementAction::All) {
|
||||
int num = this->partIndex.getNum();
|
||||
this->selectionIndex.setNum(num);
|
||||
int32_t* v = this->selectionIndex.startEditing();
|
||||
for (int i=0; i<num;i++)
|
||||
v[i] = i;
|
||||
this->selectionIndex.finishEditing();
|
||||
return;
|
||||
}
|
||||
else if (selaction->getType() == Gui::SoSelectionElementAction::None) {
|
||||
this->selectionIndex.setNum(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const SoDetail* detail = selaction->getElement();
|
||||
if (detail) {
|
||||
if (!detail->isOfType(SoFaceDetail::getClassTypeId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index = static_cast<const SoFaceDetail*>(detail)->getPartIndex();
|
||||
switch (selaction->getType()) {
|
||||
case Gui::SoSelectionElementAction::Append:
|
||||
{
|
||||
int start = this->selectionIndex.getNum();
|
||||
this->selectionIndex.set1Value(start, index);
|
||||
}
|
||||
break;
|
||||
case Gui::SoSelectionElementAction::Remove:
|
||||
{
|
||||
int start = this->selectionIndex.find(index);
|
||||
this->selectionIndex.deleteValues(start,1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inherited::doAction(action);
|
||||
}
|
||||
|
||||
void SoBrepFaceSet::GLRender(SoGLRenderAction *action)
|
||||
{
|
||||
SoState * state = action->getState();
|
||||
|
||||
SoMaterialBundle mb(action);
|
||||
Binding mbind = this->findMaterialBinding(state);
|
||||
|
||||
SoTextureCoordinateBundle tb(action, TRUE, FALSE);
|
||||
SbBool doTextures = tb.needCoordinates();
|
||||
|
||||
int32_t hl_idx = this->highlightIndex.getValue();
|
||||
int32_t num_selected = this->selectionIndex.getNum();
|
||||
|
||||
if (this->coordIndex.getNum() < 3)
|
||||
return;
|
||||
if (num_selected > 0)
|
||||
renderSelection(action);
|
||||
if (hl_idx >= 0)
|
||||
renderHighlight(action);
|
||||
|
||||
// When setting transparency shouldGLRender() handles the rendering and returns false.
|
||||
// Therefore generatePrimitives() needs to be re-implemented to handle the materials
|
||||
// correctly.
|
||||
if (!this->shouldGLRender(action))
|
||||
return;
|
||||
|
||||
#ifdef RENDER_GLARRAYS
|
||||
if (!doTextures && index_array.size() && hl_idx < 0 && num_selected <= 0) {
|
||||
if (mbind == 0) {
|
||||
mb.sendFirst(); // only one material -> apply it!
|
||||
renderSimpleArray();
|
||||
return;
|
||||
}
|
||||
else if (mbind == 1) {
|
||||
renderColoredArray(&mb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Binding nbind = this->findNormalBinding(state);
|
||||
|
||||
const SoCoordinateElement * coords;
|
||||
const SbVec3f * normals;
|
||||
const int32_t * cindices;
|
||||
int numindices;
|
||||
const int32_t * nindices;
|
||||
const int32_t * tindices;
|
||||
const int32_t * mindices;
|
||||
const int32_t * pindices;
|
||||
int numparts;
|
||||
SbBool normalCacheUsed;
|
||||
|
||||
SbBool sendNormals = !mb.isColorOnly() || tb.isFunction();
|
||||
|
||||
this->getVertexData(state, coords, normals, cindices,
|
||||
nindices, tindices, mindices, numindices,
|
||||
sendNormals, normalCacheUsed);
|
||||
|
||||
mb.sendFirst(); // make sure we have the correct material
|
||||
|
||||
// just in case someone forgot
|
||||
if (!mindices) mindices = cindices;
|
||||
if (!nindices) nindices = cindices;
|
||||
pindices = this->partIndex.getValues(0);
|
||||
numparts = this->partIndex.getNum();
|
||||
|
||||
renderShape(static_cast<const SoGLCoordinateElement*>(coords), cindices, numindices,
|
||||
pindices, numparts, normals, nindices, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0);
|
||||
|
||||
// Disable caching for this node
|
||||
SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DONT_AUTO_CACHE);
|
||||
|
||||
// Workaround for #0000433
|
||||
//#if !defined(FC_OS_WIN32)
|
||||
if (hl_idx >= 0)
|
||||
renderHighlight(action);
|
||||
if (num_selected > 0)
|
||||
renderSelection(action);
|
||||
//#endif
|
||||
}
|
||||
|
||||
void SoBrepFaceSet::GLRenderBelowPath(SoGLRenderAction * action)
|
||||
{
|
||||
inherited::GLRenderBelowPath(action);
|
||||
}
|
||||
|
||||
// this macro actually makes the code below more readable :-)
|
||||
#define DO_VERTEX(idx) \
|
||||
if (mbind == PER_VERTEX) { \
|
||||
pointDetail.setMaterialIndex(matnr); \
|
||||
vertex.setMaterialIndex(matnr++); \
|
||||
} \
|
||||
else if (mbind == PER_VERTEX_INDEXED) { \
|
||||
pointDetail.setMaterialIndex(*mindices); \
|
||||
vertex.setMaterialIndex(*mindices++); \
|
||||
} \
|
||||
if (nbind == PER_VERTEX) { \
|
||||
pointDetail.setNormalIndex(normnr); \
|
||||
currnormal = &normals[normnr++]; \
|
||||
vertex.setNormal(*currnormal); \
|
||||
} \
|
||||
else if (nbind == PER_VERTEX_INDEXED) { \
|
||||
pointDetail.setNormalIndex(*nindices); \
|
||||
currnormal = &normals[*nindices++]; \
|
||||
vertex.setNormal(*currnormal); \
|
||||
} \
|
||||
if (tb.isFunction()) { \
|
||||
vertex.setTextureCoords(tb.get(coords->get3(idx), *currnormal)); \
|
||||
if (tb.needIndices()) pointDetail.setTextureCoordIndex(tindices ? *tindices++ : texidx++); \
|
||||
} \
|
||||
else if (tbind != NONE) { \
|
||||
pointDetail.setTextureCoordIndex(tindices ? *tindices : texidx); \
|
||||
vertex.setTextureCoords(tb.get(tindices ? *tindices++ : texidx++)); \
|
||||
} \
|
||||
vertex.setPoint(coords->get3(idx)); \
|
||||
pointDetail.setCoordinateIndex(idx); \
|
||||
this->shapeVertex(&vertex);
|
||||
|
||||
void SoBrepFaceSet::generatePrimitives(SoAction * action)
|
||||
{
|
||||
//TODO
|
||||
#if 0
|
||||
inherited::generatePrimitives(action);
|
||||
#else
|
||||
//This is highly experimental!!!
|
||||
|
||||
if (this->coordIndex.getNum() < 3) return;
|
||||
|
||||
SoState * state = action->getState();
|
||||
|
||||
if (this->vertexProperty.getValue()) {
|
||||
state->push();
|
||||
this->vertexProperty.getValue()->doAction(action);
|
||||
}
|
||||
|
||||
Binding mbind = this->findMaterialBinding(state);
|
||||
Binding nbind = this->findNormalBinding(state);
|
||||
|
||||
const SoCoordinateElement * coords;
|
||||
const SbVec3f * normals;
|
||||
const int32_t * cindices;
|
||||
int numindices;
|
||||
const int32_t * nindices;
|
||||
const int32_t * tindices;
|
||||
const int32_t * mindices;
|
||||
SbBool doTextures;
|
||||
SbBool sendNormals;
|
||||
SbBool normalCacheUsed;
|
||||
|
||||
sendNormals = TRUE; // always generate normals
|
||||
|
||||
this->getVertexData(state, coords, normals, cindices,
|
||||
nindices, tindices, mindices, numindices,
|
||||
sendNormals, normalCacheUsed);
|
||||
|
||||
SoTextureCoordinateBundle tb(action, FALSE, FALSE);
|
||||
doTextures = tb.needCoordinates();
|
||||
|
||||
if (!sendNormals) nbind = OVERALL;
|
||||
else if (normalCacheUsed && nbind == PER_VERTEX) {
|
||||
nbind = PER_VERTEX_INDEXED;
|
||||
}
|
||||
else if (normalCacheUsed && nbind == PER_FACE_INDEXED) {
|
||||
nbind = PER_FACE;
|
||||
}
|
||||
|
||||
if (this->getNodeType() == SoNode::VRML1) {
|
||||
// For VRML1, PER_VERTEX means per vertex in shape, not PER_VERTEX
|
||||
// on the state.
|
||||
if (mbind == PER_VERTEX) {
|
||||
mbind = PER_VERTEX_INDEXED;
|
||||
mindices = cindices;
|
||||
}
|
||||
if (nbind == PER_VERTEX) {
|
||||
nbind = PER_VERTEX_INDEXED;
|
||||
nindices = cindices;
|
||||
}
|
||||
}
|
||||
|
||||
Binding tbind = NONE;
|
||||
if (doTextures) {
|
||||
if (tb.isFunction() && !tb.needIndices()) {
|
||||
tbind = NONE;
|
||||
tindices = NULL;
|
||||
}
|
||||
// FIXME: just call inherited::areTexCoordsIndexed() instead of
|
||||
// the if-check? 20020110 mortene.
|
||||
else if (SoTextureCoordinateBindingElement::get(state) ==
|
||||
SoTextureCoordinateBindingElement::PER_VERTEX) {
|
||||
tbind = PER_VERTEX;
|
||||
tindices = NULL;
|
||||
}
|
||||
else {
|
||||
tbind = PER_VERTEX_INDEXED;
|
||||
if (tindices == NULL) tindices = cindices;
|
||||
}
|
||||
}
|
||||
|
||||
if (nbind == PER_VERTEX_INDEXED && nindices == NULL) {
|
||||
nindices = cindices;
|
||||
}
|
||||
if (mbind == PER_VERTEX_INDEXED && mindices == NULL) {
|
||||
mindices = cindices;
|
||||
}
|
||||
|
||||
int texidx = 0;
|
||||
TriangleShape mode = POLYGON;
|
||||
TriangleShape newmode;
|
||||
const int32_t *viptr = cindices;
|
||||
const int32_t *viendptr = viptr + numindices;
|
||||
const int32_t *piptr = this->partIndex.getValues(0);
|
||||
int num_partindices = this->partIndex.getNum();
|
||||
const int32_t *piendptr = piptr + num_partindices;
|
||||
int32_t v1, v2, v3, v4, v5 = 0, pi; // v5 init unnecessary, but kills a compiler warning.
|
||||
|
||||
SoPrimitiveVertex vertex;
|
||||
SoPointDetail pointDetail;
|
||||
SoFaceDetail faceDetail;
|
||||
|
||||
vertex.setDetail(&pointDetail);
|
||||
|
||||
SbVec3f dummynormal(0,0,1);
|
||||
const SbVec3f *currnormal = &dummynormal;
|
||||
if (normals) currnormal = normals;
|
||||
vertex.setNormal(*currnormal);
|
||||
|
||||
int matnr = 0;
|
||||
int normnr = 0;
|
||||
int trinr = 0;
|
||||
pi = piptr < piendptr ? *piptr++ : -1;
|
||||
while (pi == 0) {
|
||||
// It may happen that a part has no triangles
|
||||
pi = piptr < piendptr ? *piptr++ : -1;
|
||||
if (mbind == PER_PART)
|
||||
matnr++;
|
||||
else if (mbind == PER_PART_INDEXED)
|
||||
mindices++;
|
||||
}
|
||||
|
||||
while (viptr + 2 < viendptr) {
|
||||
v1 = *viptr++;
|
||||
v2 = *viptr++;
|
||||
v3 = *viptr++;
|
||||
if (v1 < 0 || v2 < 0 || v3 < 0) {
|
||||
break;
|
||||
}
|
||||
v4 = viptr < viendptr ? *viptr++ : -1;
|
||||
if (v4 < 0) newmode = TRIANGLES;
|
||||
else {
|
||||
v5 = viptr < viendptr ? *viptr++ : -1;
|
||||
if (v5 < 0) newmode = QUADS;
|
||||
else newmode = POLYGON;
|
||||
}
|
||||
if (newmode != mode) {
|
||||
if (mode != POLYGON) this->endShape();
|
||||
mode = newmode;
|
||||
this->beginShape(action, mode, &faceDetail);
|
||||
}
|
||||
else if (mode == POLYGON) this->beginShape(action, POLYGON, &faceDetail);
|
||||
|
||||
// vertex 1 can't use DO_VERTEX
|
||||
if (mbind == PER_PART) {
|
||||
if (trinr == 0) {
|
||||
pointDetail.setMaterialIndex(matnr);
|
||||
vertex.setMaterialIndex(matnr++);
|
||||
}
|
||||
}
|
||||
else if (mbind == PER_PART_INDEXED) {
|
||||
if (trinr == 0) {
|
||||
pointDetail.setMaterialIndex(*mindices);
|
||||
vertex.setMaterialIndex(*mindices++);
|
||||
}
|
||||
}
|
||||
else if (mbind == PER_VERTEX || mbind == PER_FACE) {
|
||||
pointDetail.setMaterialIndex(matnr);
|
||||
vertex.setMaterialIndex(matnr++);
|
||||
}
|
||||
else if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) {
|
||||
pointDetail.setMaterialIndex(*mindices);
|
||||
vertex.setMaterialIndex(*mindices++);
|
||||
}
|
||||
if (nbind == PER_VERTEX || nbind == PER_FACE) {
|
||||
pointDetail.setNormalIndex(normnr);
|
||||
currnormal = &normals[normnr++];
|
||||
vertex.setNormal(*currnormal);
|
||||
}
|
||||
else if (nbind == PER_FACE_INDEXED || nbind == PER_VERTEX_INDEXED) {
|
||||
pointDetail.setNormalIndex(*nindices);
|
||||
currnormal = &normals[*nindices++];
|
||||
vertex.setNormal(*currnormal);
|
||||
}
|
||||
|
||||
if (tb.isFunction()) {
|
||||
vertex.setTextureCoords(tb.get(coords->get3(v1), *currnormal));
|
||||
if (tb.needIndices()) pointDetail.setTextureCoordIndex(tindices ? *tindices++ : texidx++);
|
||||
}
|
||||
else if (tbind != NONE) {
|
||||
pointDetail.setTextureCoordIndex(tindices ? *tindices : texidx);
|
||||
vertex.setTextureCoords(tb.get(tindices ? *tindices++ : texidx++));
|
||||
}
|
||||
pointDetail.setCoordinateIndex(v1);
|
||||
vertex.setPoint(coords->get3(v1));
|
||||
this->shapeVertex(&vertex);
|
||||
|
||||
DO_VERTEX(v2);
|
||||
DO_VERTEX(v3);
|
||||
|
||||
if (mode != TRIANGLES) {
|
||||
DO_VERTEX(v4);
|
||||
if (mode == POLYGON) {
|
||||
DO_VERTEX(v5);
|
||||
v1 = viptr < viendptr ? *viptr++ : -1;
|
||||
while (v1 >= 0) {
|
||||
DO_VERTEX(v1);
|
||||
v1 = viptr < viendptr ? *viptr++ : -1;
|
||||
}
|
||||
this->endShape();
|
||||
}
|
||||
}
|
||||
faceDetail.incFaceIndex();
|
||||
if (mbind == PER_VERTEX_INDEXED) {
|
||||
mindices++;
|
||||
}
|
||||
if (nbind == PER_VERTEX_INDEXED) {
|
||||
nindices++;
|
||||
}
|
||||
if (tindices) tindices++;
|
||||
|
||||
trinr++;
|
||||
if (pi == trinr) {
|
||||
pi = piptr < piendptr ? *piptr++ : -1;
|
||||
while (pi == 0) {
|
||||
// It may happen that a part has no triangles
|
||||
pi = piptr < piendptr ? *piptr++ : -1;
|
||||
if (mbind == PER_PART)
|
||||
matnr++;
|
||||
else if (mbind == PER_PART_INDEXED)
|
||||
mindices++;
|
||||
}
|
||||
trinr = 0;
|
||||
}
|
||||
}
|
||||
if (mode != POLYGON) this->endShape();
|
||||
|
||||
if (normalCacheUsed) {
|
||||
this->readUnlockNormalCache();
|
||||
}
|
||||
|
||||
if (this->vertexProperty.getValue()) {
|
||||
state->pop();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef DO_VERTEX
|
||||
|
||||
void SoBrepFaceSet::renderHighlight(SoGLRenderAction *action)
|
||||
{
|
||||
SoState * state = action->getState();
|
||||
state->push();
|
||||
|
||||
SoLazyElement::setEmissive(state, &this->highlightColor);
|
||||
SoOverrideElement::setEmissiveColorOverride(state, this, TRUE);
|
||||
#if 0 // disables shading effect
|
||||
// sendNormals will be FALSE
|
||||
SoLazyElement::setDiffuse(state, this,1, &this->highlightColor,&this->colorpacker);
|
||||
SoOverrideElement::setDiffuseColorOverride(state, this, TRUE);
|
||||
SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
|
||||
#endif
|
||||
|
||||
Binding mbind = this->findMaterialBinding(state);
|
||||
Binding nbind = this->findNormalBinding(state);
|
||||
|
||||
const SoCoordinateElement * coords;
|
||||
const SbVec3f * normals;
|
||||
const int32_t * cindices;
|
||||
int numindices;
|
||||
const int32_t * nindices;
|
||||
const int32_t * tindices;
|
||||
const int32_t * mindices;
|
||||
const int32_t * pindices;
|
||||
SbBool doTextures;
|
||||
SbBool normalCacheUsed;
|
||||
|
||||
SoMaterialBundle mb(action);
|
||||
SoTextureCoordinateBundle tb(action, TRUE, FALSE);
|
||||
doTextures = tb.needCoordinates();
|
||||
SbBool sendNormals = !mb.isColorOnly() || tb.isFunction();
|
||||
|
||||
this->getVertexData(state, coords, normals, cindices,
|
||||
nindices, tindices, mindices, numindices,
|
||||
sendNormals, normalCacheUsed);
|
||||
|
||||
mb.sendFirst(); // make sure we have the correct material
|
||||
|
||||
int32_t id = this->highlightIndex.getValue();
|
||||
|
||||
// just in case someone forgot
|
||||
if (!mindices) mindices = cindices;
|
||||
if (!nindices) nindices = cindices;
|
||||
pindices = this->partIndex.getValues(0);
|
||||
|
||||
// coords
|
||||
int length = (int)pindices[id]*4;
|
||||
int start=0;
|
||||
for (int i=0;i<id;i++)
|
||||
start+=(int)pindices[i];
|
||||
start *= 4;
|
||||
|
||||
// normals
|
||||
if (nbind == PER_VERTEX_INDEXED)
|
||||
nindices = &(nindices[start]);
|
||||
else if (nbind == PER_VERTEX)
|
||||
normals = &(normals[start]);
|
||||
else
|
||||
nbind = OVERALL;
|
||||
|
||||
// materials
|
||||
mbind = OVERALL;
|
||||
doTextures = FALSE;
|
||||
|
||||
renderShape(static_cast<const SoGLCoordinateElement*>(coords), &(cindices[start]), length,
|
||||
&(pindices[id]), 1, normals, nindices, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0);
|
||||
state->pop();
|
||||
}
|
||||
|
||||
void SoBrepFaceSet::renderSelection(SoGLRenderAction *action)
|
||||
{
|
||||
int numSelected = this->selectionIndex.getNum();
|
||||
const int32_t* selected = this->selectionIndex.getValues(0);
|
||||
if (numSelected == 0) return;
|
||||
|
||||
SoState * state = action->getState();
|
||||
state->push();
|
||||
|
||||
SoLazyElement::setEmissive(state, &this->selectionColor);
|
||||
SoOverrideElement::setEmissiveColorOverride(state, this, TRUE);
|
||||
#if 0 // disables shading effect
|
||||
SoLazyElement::setDiffuse(state, this,1, &this->selectionColor,&this->colorpacker);
|
||||
SoOverrideElement::setDiffuseColorOverride(state, this, TRUE);
|
||||
SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
|
||||
#endif
|
||||
|
||||
Binding mbind = this->findMaterialBinding(state);
|
||||
Binding nbind = this->findNormalBinding(state);
|
||||
|
||||
const SoCoordinateElement * coords;
|
||||
const SbVec3f * normals;
|
||||
const int32_t * cindices;
|
||||
int numindices;
|
||||
const int32_t * nindices;
|
||||
const int32_t * tindices;
|
||||
const int32_t * mindices;
|
||||
const int32_t * pindices;
|
||||
SbBool doTextures;
|
||||
SbBool normalCacheUsed;
|
||||
|
||||
SoMaterialBundle mb(action);
|
||||
SoTextureCoordinateBundle tb(action, TRUE, FALSE);
|
||||
doTextures = tb.needCoordinates();
|
||||
SbBool sendNormals = !mb.isColorOnly() || tb.isFunction();
|
||||
|
||||
this->getVertexData(state, coords, normals, cindices,
|
||||
nindices, tindices, mindices, numindices,
|
||||
sendNormals, normalCacheUsed);
|
||||
|
||||
mb.sendFirst(); // make sure we have the correct material
|
||||
|
||||
// just in case someone forgot
|
||||
if (!mindices) mindices = cindices;
|
||||
if (!nindices) nindices = cindices;
|
||||
pindices = this->partIndex.getValues(0);
|
||||
|
||||
// materials
|
||||
mbind = OVERALL;
|
||||
doTextures = FALSE;
|
||||
|
||||
for (int i=0; i<numSelected; i++) {
|
||||
int id = selected[i];
|
||||
|
||||
// coords
|
||||
int length = (int)pindices[id]*4;
|
||||
int start=0;
|
||||
for (int j=0;j<id;j++)
|
||||
start+=(int)pindices[j];
|
||||
start *= 4;
|
||||
|
||||
// normals
|
||||
const SbVec3f * normals_s = normals;
|
||||
const int32_t * nindices_s = nindices;
|
||||
if (nbind == PER_VERTEX_INDEXED)
|
||||
nindices_s = &(nindices[start]);
|
||||
else if (nbind == PER_VERTEX)
|
||||
normals_s = &(normals[start]);
|
||||
else
|
||||
nbind = OVERALL;
|
||||
|
||||
renderShape(static_cast<const SoGLCoordinateElement*>(coords), &(cindices[start]), length,
|
||||
&(pindices[id]), 1, normals_s, nindices_s, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0);
|
||||
}
|
||||
state->pop();
|
||||
}
|
||||
|
||||
|
||||
SoDetail * SoBrepFaceSet::createTriangleDetail(SoRayPickAction * action,
|
||||
const SoPrimitiveVertex * v1,
|
||||
const SoPrimitiveVertex * v2,
|
||||
const SoPrimitiveVertex * v3,
|
||||
SoPickedPoint * pp)
|
||||
{
|
||||
SoDetail* detail = inherited::createTriangleDetail(action, v1, v2, v3, pp);
|
||||
const int32_t * indices = this->partIndex.getValues(0);
|
||||
int num = this->partIndex.getNum();
|
||||
if (indices) {
|
||||
SoFaceDetail* face_detail = static_cast<SoFaceDetail*>(detail);
|
||||
int index = face_detail->getFaceIndex();
|
||||
int count = 0;
|
||||
for (int i=0; i<num; i++) {
|
||||
count += indices[i];
|
||||
if (index < count) {
|
||||
face_detail->setPartIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return detail;
|
||||
}
|
||||
|
||||
SoBrepFaceSet::Binding
|
||||
SoBrepFaceSet::findMaterialBinding(SoState * const state) const
|
||||
{
|
||||
Binding binding = OVERALL;
|
||||
SoMaterialBindingElement::Binding matbind =
|
||||
SoMaterialBindingElement::get(state);
|
||||
|
||||
switch (matbind) {
|
||||
case SoMaterialBindingElement::OVERALL:
|
||||
binding = OVERALL;
|
||||
break;
|
||||
case SoMaterialBindingElement::PER_VERTEX:
|
||||
binding = PER_VERTEX;
|
||||
break;
|
||||
case SoMaterialBindingElement::PER_VERTEX_INDEXED:
|
||||
binding = PER_VERTEX_INDEXED;
|
||||
break;
|
||||
case SoMaterialBindingElement::PER_PART:
|
||||
binding = PER_PART;
|
||||
break;
|
||||
case SoMaterialBindingElement::PER_FACE:
|
||||
binding = PER_FACE;
|
||||
break;
|
||||
case SoMaterialBindingElement::PER_PART_INDEXED:
|
||||
binding = PER_PART_INDEXED;
|
||||
break;
|
||||
case SoMaterialBindingElement::PER_FACE_INDEXED:
|
||||
binding = PER_FACE_INDEXED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
|
||||
SoBrepFaceSet::Binding
|
||||
SoBrepFaceSet::findNormalBinding(SoState * const state) const
|
||||
{
|
||||
Binding binding = PER_VERTEX_INDEXED;
|
||||
SoNormalBindingElement::Binding normbind =
|
||||
(SoNormalBindingElement::Binding) SoNormalBindingElement::get(state);
|
||||
|
||||
switch (normbind) {
|
||||
case SoNormalBindingElement::OVERALL:
|
||||
binding = OVERALL;
|
||||
break;
|
||||
case SoNormalBindingElement::PER_VERTEX:
|
||||
binding = PER_VERTEX;
|
||||
break;
|
||||
case SoNormalBindingElement::PER_VERTEX_INDEXED:
|
||||
binding = PER_VERTEX_INDEXED;
|
||||
break;
|
||||
case SoNormalBindingElement::PER_PART:
|
||||
binding = PER_PART;
|
||||
break;
|
||||
case SoNormalBindingElement::PER_FACE:
|
||||
binding = PER_FACE;
|
||||
break;
|
||||
case SoNormalBindingElement::PER_PART_INDEXED:
|
||||
binding = PER_PART_INDEXED;
|
||||
break;
|
||||
case SoNormalBindingElement::PER_FACE_INDEXED:
|
||||
binding = PER_FACE_INDEXED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************
|
||||
// renderShape: fallback rendering: one vertex at a time
|
||||
//
|
||||
void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist,
|
||||
const int32_t *vertexindices,
|
||||
int num_indices,
|
||||
const int32_t *partindices,
|
||||
int num_partindices,
|
||||
const SbVec3f *normals,
|
||||
const int32_t *normalindices,
|
||||
SoMaterialBundle *const materials,
|
||||
const int32_t *matindices,
|
||||
SoTextureCoordinateBundle * const texcoords,
|
||||
const int32_t *texindices,
|
||||
const int nbind,
|
||||
const int mbind,
|
||||
const int texture)
|
||||
{
|
||||
int texidx = 0;
|
||||
|
||||
const SbVec3f * coords3d = NULL;
|
||||
coords3d = vertexlist->getArrayPtr3();
|
||||
|
||||
const int32_t *viptr = vertexindices;
|
||||
const int32_t *viendptr = viptr + num_indices;
|
||||
const int32_t *piptr = partindices;
|
||||
const int32_t *piendptr = piptr + num_partindices;
|
||||
int32_t v1, v2, v3, v4, pi;
|
||||
SbVec3f dummynormal(0,0,1);
|
||||
int numverts = vertexlist->getNum();
|
||||
|
||||
const SbVec3f *currnormal = &dummynormal;
|
||||
if (normals) currnormal = normals;
|
||||
|
||||
int matnr = 0;
|
||||
int trinr = 0;
|
||||
pi = piptr < piendptr ? *piptr++ : -1;
|
||||
while (pi == 0) {
|
||||
// It may happen that a part has no triangles
|
||||
pi = piptr < piendptr ? *piptr++ : -1;
|
||||
if (mbind == PER_PART)
|
||||
matnr++;
|
||||
else if (mbind == PER_PART_INDEXED)
|
||||
matindices++;
|
||||
}
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
while (viptr + 2 < viendptr) {
|
||||
v1 = *viptr++;
|
||||
v2 = *viptr++;
|
||||
v3 = *viptr++;
|
||||
|
||||
// This test is for robustness upon buggy data sets
|
||||
if (v1 < 0 || v2 < 0 || v3 < 0 ||
|
||||
v1 >= numverts || v2 >= numverts || v3 >= numverts) {
|
||||
break;
|
||||
}
|
||||
v4 = viptr < viendptr ? *viptr++ : -1;
|
||||
|
||||
/* vertex 1 *********************************************************/
|
||||
if (mbind == PER_PART) {
|
||||
if (trinr == 0)
|
||||
materials->send(matnr++, TRUE);
|
||||
}
|
||||
else if (mbind == PER_PART_INDEXED) {
|
||||
if (trinr == 0)
|
||||
materials->send(*matindices++, TRUE);
|
||||
}
|
||||
else if (mbind == PER_VERTEX || mbind == PER_FACE) {
|
||||
materials->send(matnr++, TRUE);
|
||||
}
|
||||
else if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) {
|
||||
materials->send(*matindices++, TRUE);
|
||||
}
|
||||
|
||||
if (normals) {
|
||||
if (nbind == PER_VERTEX || nbind == PER_FACE) {
|
||||
currnormal = normals++;
|
||||
glNormal3fv((const GLfloat*)currnormal);
|
||||
}
|
||||
else if (nbind == PER_VERTEX_INDEXED || nbind == PER_FACE_INDEXED) {
|
||||
currnormal = &normals[*normalindices++];
|
||||
glNormal3fv((const GLfloat*)currnormal);
|
||||
}
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
texcoords->send(texindices ? *texindices++ : texidx++,
|
||||
vertexlist->get3(v1),
|
||||
*currnormal);
|
||||
}
|
||||
|
||||
glVertex3fv((const GLfloat*) (coords3d + v1));
|
||||
|
||||
/* vertex 2 *********************************************************/
|
||||
if (mbind == PER_VERTEX)
|
||||
materials->send(matnr++, TRUE);
|
||||
else if (mbind == PER_VERTEX_INDEXED)
|
||||
materials->send(*matindices++, TRUE);
|
||||
|
||||
if (normals) {
|
||||
if (nbind == PER_VERTEX) {
|
||||
currnormal = normals++;
|
||||
glNormal3fv((const GLfloat*)currnormal);
|
||||
}
|
||||
else if (nbind == PER_VERTEX_INDEXED) {
|
||||
currnormal = &normals[*normalindices++];
|
||||
glNormal3fv((const GLfloat*)currnormal);
|
||||
}
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
texcoords->send(texindices ? *texindices++ : texidx++,
|
||||
vertexlist->get3(v2),
|
||||
*currnormal);
|
||||
}
|
||||
|
||||
glVertex3fv((const GLfloat*) (coords3d + v2));
|
||||
|
||||
/* vertex 3 *********************************************************/
|
||||
if (mbind == PER_VERTEX)
|
||||
materials->send(matnr++, TRUE);
|
||||
else if (mbind == PER_VERTEX_INDEXED)
|
||||
materials->send(*matindices++, TRUE);
|
||||
|
||||
if (normals) {
|
||||
if (nbind == PER_VERTEX) {
|
||||
currnormal = normals++;
|
||||
glNormal3fv((const GLfloat*)currnormal);
|
||||
}
|
||||
else if (nbind == PER_VERTEX_INDEXED) {
|
||||
currnormal = &normals[*normalindices++];
|
||||
glNormal3fv((const GLfloat*)currnormal);
|
||||
}
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
texcoords->send(texindices ? *texindices++ : texidx++,
|
||||
vertexlist->get3(v3),
|
||||
*currnormal);
|
||||
}
|
||||
|
||||
glVertex3fv((const GLfloat*) (coords3d + v3));
|
||||
|
||||
if (mbind == PER_VERTEX_INDEXED)
|
||||
matindices++;
|
||||
|
||||
if (nbind == PER_VERTEX_INDEXED)
|
||||
normalindices++;
|
||||
|
||||
if (texture && texindices) {
|
||||
texindices++;
|
||||
}
|
||||
|
||||
trinr++;
|
||||
if (pi == trinr) {
|
||||
pi = piptr < piendptr ? *piptr++ : -1;
|
||||
while (pi == 0) {
|
||||
// It may happen that a part has no triangles
|
||||
pi = piptr < piendptr ? *piptr++ : -1;
|
||||
if (mbind == PER_PART)
|
||||
matnr++;
|
||||
else if (mbind == PER_PART_INDEXED)
|
||||
matindices++;
|
||||
}
|
||||
trinr = 0;
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
#ifdef RENDER_GLARRAYS
|
||||
//****************************************************************************
|
||||
// renderSimpleArray: normal and coord from vertex_array;
|
||||
// no texture, color, highlight or selection but highet possible speed;
|
||||
// all vertices written in one go!
|
||||
//
|
||||
void SoBrepFaceSet::renderSimpleArray()
|
||||
{
|
||||
int cnt = index_array.size();
|
||||
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glInterleavedArrays(GL_N3F_V3F, 0, vertex_array.data());
|
||||
glDrawElements(GL_TRIANGLES, cnt, GL_UNSIGNED_INT, index_array.data());
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef RENDER_GLARRAYS
|
||||
//****************************************************************************
|
||||
// renderColoredArray: normal and coord from vertex_array;
|
||||
// no texture, highlight or selection but color / material array.
|
||||
// needs to iterate over parts (i.e. geometry faces)
|
||||
//
|
||||
void SoBrepFaceSet::renderColoredArray(SoMaterialBundle *const materials)
|
||||
{
|
||||
int num_parts = partIndex.getNum();
|
||||
int cnt = index_array.size();
|
||||
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glInterleavedArrays(GL_N3F_V3F, 0, vertex_array.data());
|
||||
const int32_t* ptr = index_array.data();
|
||||
|
||||
for (int part_id = 0; part_id < num_parts; part_id++) {
|
||||
int tris = partIndex[part_id];
|
||||
|
||||
if (tris > 0) {
|
||||
materials->send(part_id, TRUE);
|
||||
glDrawElements(GL_TRIANGLES, 3 * tris, GL_UNSIGNED_INT, ptr);
|
||||
ptr += 3 * tris;
|
||||
}
|
||||
}
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
128
src/Mod/Part/Gui/SoBrepFaceSet.h
Normal file
128
src/Mod/Part/Gui/SoBrepFaceSet.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef PARTGUI_SOBREPFACESET_H
|
||||
#define PARTGUI_SOBREPFACESET_H
|
||||
#if 0
|
||||
#include <Inventor/fields/SoMFInt32.h>
|
||||
#include <Inventor/fields/SoSFNode.h>
|
||||
#include <Inventor/fields/SoSubField.h>
|
||||
#include <Inventor/nodes/SoSubNode.h>
|
||||
#include <Inventor/nodes/SoIndexedFaceSet.h>
|
||||
#include <Inventor/nodes/SoIndexedLineSet.h>
|
||||
#include <Inventor/nodes/SoPointSet.h>
|
||||
#include <Inventor/elements/SoLazyElement.h>
|
||||
#include <Inventor/elements/SoReplacedElement.h>
|
||||
#include <vector>
|
||||
|
||||
class SoGLCoordinateElement;
|
||||
class SoTextureCoordinateBundle;
|
||||
|
||||
|
||||
#define RENDER_GLARRAYS
|
||||
|
||||
namespace PartGui {
|
||||
|
||||
class VertexArray;
|
||||
|
||||
|
||||
class PartGuiExport SoBrepFaceSet : public SoIndexedFaceSet {
|
||||
typedef SoIndexedFaceSet inherited;
|
||||
|
||||
SO_NODE_HEADER(SoBrepFaceSet);
|
||||
|
||||
public:
|
||||
static void initClass();
|
||||
SoBrepFaceSet();
|
||||
|
||||
SoMFInt32 partIndex;
|
||||
SoSFInt32 highlightIndex;
|
||||
SoMFInt32 selectionIndex;
|
||||
|
||||
#ifdef RENDER_GLARRAYS
|
||||
std::vector<int32_t> index_array;
|
||||
std::vector<float> vertex_array;
|
||||
#endif
|
||||
|
||||
enum Binding {
|
||||
OVERALL = 0,
|
||||
PER_PART,
|
||||
PER_PART_INDEXED,
|
||||
PER_FACE,
|
||||
PER_FACE_INDEXED,
|
||||
PER_VERTEX,
|
||||
PER_VERTEX_INDEXED,
|
||||
NONE = OVERALL
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual ~SoBrepFaceSet();
|
||||
virtual void GLRender(SoGLRenderAction *action);
|
||||
virtual void GLRenderBelowPath(SoGLRenderAction * action);
|
||||
virtual void doAction(SoAction* action);
|
||||
virtual SoDetail * createTriangleDetail(
|
||||
SoRayPickAction * action,
|
||||
const SoPrimitiveVertex * v1,
|
||||
const SoPrimitiveVertex * v2,
|
||||
const SoPrimitiveVertex * v3,
|
||||
SoPickedPoint * pp);
|
||||
virtual void generatePrimitives(SoAction * action);
|
||||
|
||||
private:
|
||||
Binding findMaterialBinding(SoState * const state) const;
|
||||
Binding findNormalBinding(SoState * const state) const;
|
||||
void renderHighlight(SoGLRenderAction *action);
|
||||
void renderSelection(SoGLRenderAction *action);
|
||||
|
||||
|
||||
// low-level render functions
|
||||
|
||||
void renderShape(const SoGLCoordinateElement * const vertexlist,
|
||||
const int32_t *vertexindices,
|
||||
int num_vertexindices,
|
||||
const int32_t *partindices,
|
||||
int num_partindices,
|
||||
const SbVec3f *normals,
|
||||
const int32_t *normindices,
|
||||
SoMaterialBundle *const materials,
|
||||
const int32_t *matindices,
|
||||
SoTextureCoordinateBundle * const texcoords,
|
||||
const int32_t *texindices,
|
||||
const int nbind,
|
||||
const int mbind,
|
||||
const int texture);
|
||||
|
||||
#ifdef RENDER_GLARRAYS
|
||||
void renderSimpleArray();
|
||||
void renderColoredArray(SoMaterialBundle *const materials);
|
||||
#endif
|
||||
|
||||
private:
|
||||
SbColor selectionColor;
|
||||
SbColor highlightColor;
|
||||
SoColorPacker colorpacker;
|
||||
};
|
||||
|
||||
} // namespace PartGui
|
||||
#endif
|
||||
#endif // PARTGUI_SOBREPFACESET_H
|
||||
|
|
@ -102,6 +102,7 @@
|
|||
|
||||
#include "ViewProviderExt.h"
|
||||
#include "SoBrepShape.h"
|
||||
#include "SoBrepFaceSet.h"
|
||||
#include "TaskFaceColors.h"
|
||||
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
|
Loading…
Reference in New Issue
Block a user