Programujeme: Jednoduchý Bounding Box
Publikováno: 18. července 2010 | Zobrazeno: 9059x
Tento příklad je určen spíše pokročilejším, ale i začínající programátoři se podle něho mohou naučit mnoho dílčích postupů. Bounding Box je - pro ty, kdo tento pojem neznají - jakási prostorová obálka dílu (plochy, tělesa), představována nejmenším možným kvádrem, do kterého se vejde.
Možná se ptáte, k čemu je vlastně takový Bounding Box dobrý. Představte si, že máte tvarově složitý díl, který se má vyrábět vstřikováním nebo lisováním. Potřebujete rychle zjistit, jak velké budou bloky, ze kterých se bude obrábět forma. Bounding Box vám v tuhle chvíli pomůže rychle zjistit minimální rozměry bloku, který pro výrobu formy potřebujete.
Makro, které tu bude představeno, má jedno omezení. Určí nám sice nejmenší rozměry, ale musíme si nejprve vybrat směry (x,y,z), ve kterých se rozměry vypočtou. Pokud ale uvažujeme, že u lisovaného dílu stejně musíme respektovat směr formování, není toto omezení zase až tak veliké.
Dívejme se na makro tedy spíše jako na pomůcku pro rychlý návrh bloku(ů) při konstrukci tvarovacích nástrojů.
Protože pracujeme s CATScriptem, není třeba deklarovat proměnné (pouze pole pro souřadnice a filtr u výběru).
Na začátku je třeba určit směry, ve kterých se BB vytvoří. K tomu poslouží osový kříž, který musí uživatel sám nadefinovat. Po spuštění makro uživatele vyzve, aby tento kříž vybral.
V tuto chvíli je určený souřadný systém a v proměnných jsou uložené směry vektorů jednotlivých os, které budou třeba při vytváření extrémů. Dále se pokračuje výběrem plochy pro Extract, jeho vytvořením a výpočtem extrémů.
Nyní se vytvoří šest instancí bodů, které budou vycházet z extrémů. Body se vloží do geometrického setu a pojmenují podle smyslu a směrů. Zároveň s nimi se připraví obě zmiňované roviny. "Bottom", ve které se bude následně skicovat a "Top", která určí výšku Padu.
V tomto momentě je připravené vše pro to, aby se mohlo začít se skicou, tvořící základnu BB. Velmi důležitým krokem je nastavení směru osového kříže u skicy. Pokud by se to neudělalo, osový kříž skicy by se nastavil podle absolutních souřadnic modelu.
No a to už je skoro konec. V poslední části se vytvoří samotný Pad ze skicy a jeho výška se omezí rovinou "Top". Nakonec se Pad obarví na světle zeleno a nastaví se mu průhlednost, aby nezakrýval původní model.
Zkušenější z vás naopak vyzývám k zamyšlení, co by se v tomto makru dalo zlepšit. Jeden návrh na zlepšení bych měl hned teď. Na začátku by se určil jen směr lisování (Z) a ostatní by se dopočítaly automaticky tak, aby vznikl nejmenší možný objem BB (postupně natáčet osy x,y třeba po 1° a spočítat pro každou možnost objem - pak vytvořit BB v pozici s nejmenším objemem). Dalším vylepšením by mohl být zadávaní přídavků v jednotlivých směrech atd.
Možná se ptáte, k čemu je vlastně takový Bounding Box dobrý. Představte si, že máte tvarově složitý díl, který se má vyrábět vstřikováním nebo lisováním. Potřebujete rychle zjistit, jak velké budou bloky, ze kterých se bude obrábět forma. Bounding Box vám v tuhle chvíli pomůže rychle zjistit minimální rozměry bloku, který pro výrobu formy potřebujete.
Makro, které tu bude představeno, má jedno omezení. Určí nám sice nejmenší rozměry, ale musíme si nejprve vybrat směry (x,y,z), ve kterých se rozměry vypočtou. Pokud ale uvažujeme, že u lisovaného dílu stejně musíme respektovat směr formování, není toto omezení zase až tak veliké.
Dívejme se na makro tedy spíše jako na pomůcku pro rychlý návrh bloku(ů) při konstrukci tvarovacích nástrojů.
Princip
Vlastní postup, jak BB vytvořit není zase až tak složitý. Nejprve se nadefinuje souřadný systém (osový kříž), ve kterém bude Bounding box vytvořen. Z tělesa (plochy) pro Bounding Box se pomocí fce Extract (s bodovou návazností) vytvoří plocha obepínající celé těleso. Na takto vytvořené ploše se vytvoří extrémy ve všech směrech (celkem šest bodů, MinX, MaxX atd.), jejichž směry určuje souřadný systém. Pro samotný BB se použije fce Pad s jedním limitem. Základna (a tedy i samotná skica) bude v rovině, která bude procházet extrémem MinZ a bude rovnoběžná s rovinou xy souřadného systému. Skica se vytvoří jako čtverec o velikosti 100x100, do ní se promítnou extrémy ze směrů x a y, a k takto vzniklým bodům se "přichytnou" strany čtverce. Tak vznikne základna BB. Pak již stačí jen vytáhnout Pad - omezujícím elementem bude rovina procházející extrémem MaxZ a rovnoběžná se základnou.Geometrie
V modelu se vytvoří nové Body s vnořeným geometrickým setem. Body bude pojmenováno BoundingBox.x, kde x bude počet všech Body v modelu + 1. V geometrickém setu bude šest bodů - extrému, rovina základny a omezující rovina. V Body bude pouze již zmíněný Pad. Celá geometrie je navázaná na vstupní element, takže pokud se tento bude měnit, bude se měnit i Bounding Box (proto ten název asociativní).Zdrojový kód
Celý kód bude rozdělen do několika částí, opakující se úseky budou uvádeny jen jednou. Makro funguje pouze pokud je otevřen samostatný Part, ošetření pro sestavu není zohledněno.Protože pracujeme s CATScriptem, není třeba deklarovat proměnné (pouze pole pro souřadnice a filtr u výběru).
Na začátku je třeba určit směry, ve kterých se BB vytvoří. K tomu poslouží osový kříž, který musí uživatel sám nadefinovat. Po spuštění makro uživatele vyzve, aby tento kříž vybral.
Language="VBSCRIPT"
Dim OriginCoord(2)
Dim AxisCoord(2)
Dim sFilter(0)
Sub CATMain()
'nastavime prislusne instance dokumentu, partu a vyberu
Set oActiveDocument = CATIA.ActiveDocument
Set oPart = oActiveDocument.Part
Set oSelection = CATIA.ActiveDocument.Selection
'vybereme souradny system, ve kterem se BB vytvori
oSelection.Clear
sFilter(0) = "AxisSystem"
sStatus = oSelection.SelectElement2(sFilter, " Vyberte osový kříž ...", False)
If sStatus = "Cancel" Then
Exit Sub
End If
Set oAxisSystem = oSelection.Item(1).value
oSelection.Clear
'nastavime vybrany osovy kriz jako aktualni
oAxisSystem.IsCurrent = 1
'instance objektu pro praci s plosnymi funkcemi
Set oHybridShapeFactory = oPart.HybridShapeFactory
'zjistime souradnice stredu osoveho krize
oAxisSystem.GetOrigin(OriginCoord)
CX = OriginCoord(0):CY = OriginCoord(1):CZ = OriginCoord(2)
'zjistime vektory os
oAxisSystem.GetXAxis(AxisCoord)
Set VX = oHybridShapeFactory.AddNewDirectionByCoord(AxisCoord(0), AxisCoord(1), AxisCoord(2))
VX1 = AxisCoord(0):VX2 = AxisCoord(1):VX3 = AxisCoord(2)
oAxisSystem.GetYAxis(AxisCoord)
Set VY = oHybridShapeFactory.AddNewDirectionByCoord(AxisCoord(0), AxisCoord(1), AxisCoord(2))
VY1 = AxisCoord(0):VY2 = AxisCoord(1):VY3 = AxisCoord(2)
oAxisSystem.GetZAxis(AxisCoord)
Set VZ = oHybridShapeFactory.AddNewDirectionByCoord(AxisCoord(0), AxisCoord(1), AxisCoord(2))
VZ1 = AxisCoord(0):VZ2 = AxisCoord(1):VZ3 = AxisCoord(2)
V tuto chvíli je určený souřadný systém a v proměnných jsou uložené směry vektorů jednotlivých os, které budou třeba při vytváření extrémů. Dále se pokračuje výběrem plochy pro Extract, jeho vytvořením a výpočtem extrémů.
'vybereme plochu objektu, na kterem se vytvori BB a vytvorime z ni referenci
sFilter(0) = "Face" 'vybirame pouze plochu
sStatus =oSelection.SelectElement2(sFilter, "Vyberte plochu na objektu, pro který má být vytvořen BoundingBox", False)
If (sStatus = "Cancel") Then
Exit Sub
End If
Set oReference= oSelection.Item(1).Value 'vytvorime z plochy jako referenci
'pridame Do partu prazdne Body a Geo Set a pojmenujeme je
Set oBodies = oPart.Bodies
j = oBodies.Count
Set oBody = oBodies.Add()
oBody.Name = "BoundingBox." & j
Set oHybridBodies = oBody.HybridBodies
Set oHybridBody = oHybridBodies.Add
oHybridBody.Name = "Geometry"
'skryjeme set
oSelection.Clear
oSelection.Add(oHybridBody)
oSelection.VisProperties.SetShow catVisPropertyNoShowAttr
'vytvorime extrakci z vybraneho elementu s bodovou navaznosti a vytvorime z ni referenci
Set oHybridShapeExtract = oHybridShapeFactory.AddNewExtract(oReference)
oHybridShapeExtract.PropagationType = 1
oHybridShapeExtract.ComplementaryExtract = False
oHybridShapeExtract.IsFederated = False
Set oReference = oHybridShapeExtract
'urcime extremy ve vsech smerech
Set oExt1 = oHybridShapeFactory.AddNewExtremum (oReference, VX, 1)
Set oExt2 = oHybridShapeFactory.AddNewExtremum (oReference, VX, 0)
Set oExt3 = oHybridShapeFactory.AddNewExtremum (oReference, VY, 1)
Set oExt4 = oHybridShapeFactory.AddNewExtremum (oReference, VY, 0)
Set oExt5 = oHybridShapeFactory.AddNewExtremum (oReference, VZ, 1)
Set oExt6 = oHybridShapeFactory.AddNewExtremum (oReference, VZ, 0)
oPart.Update
Nyní se vytvoří šest instancí bodů, které budou vycházet z extrémů. Body se vloží do geometrického setu a pojmenují podle smyslu a směrů. Zároveň s nimi se připraví obě zmiňované roviny. "Bottom", ve které se bude následně skicovat a "Top", která určí výšku Padu.
'vytvorime 6 bodu podle extremu
Set oReference = oPart.CreateReferenceFromObject(oExt1)
Set oMinX = oHybridShapeFactory.AddNewPointCoordWithReference(0, 0, 0, oReference)
oHybridBody.AppendHybridShape oMinX
oMinX.Name = "Min.X"
Set oReference = oPart.CreateReferenceFromObject(oExt2)
Set oMaxX = oHybridShapeFactory.AddNewPointCoordWithReference(0, 0, 0, oReference)
oHybridBody.AppendHybridShape oMaxX
oMaxX.Name = "Max.X"
Set oReference = oPart.CreateReferenceFromObject(oExt3)
Set oMinY = oHybridShapeFactory.AddNewPointCoordWithReference(0, 0, 0, oReference)
oHybridBody.AppendHybridShape oMinY
oMinY.Name = "Min.Y"
Set oReference = oPart.CreateReferenceFromObject(oExt4)
Set oMaxY = oHybridShapeFactory.AddNewPointCoordWithReference(0, 0, 0, oReference)
oHybridBody.AppendHybridShape oMaxY
oMaxY.Name = "Max.Y"
Set oReference = oPart.CreateReferenceFromObject(oExt5)
Set oMinZ = oHybridShapeFactory.AddNewPointCoordWithReference(0, 0, 0, oReference)
oHybridBody.AppendHybridShape oMinZ
oMinZ.Name = "Min.Z"
Set oReference = oPart.CreateReferenceFromObject(oExt6)
Set oMaxZ = oHybridShapeFactory.AddNewPointCoordWithReference(0, 0, 0, oReference)
oHybridBody.AppendHybridShape oMaxZ
oMaxZ.Name = "Max.Z"
Set MaxZ = oPart.CreateReferenceFromObject(oMaxZ)
'vytvorime rovinu Bottom, Do ktere budeme skicovat zakladnu BB
Set oReference = oPart.CreateReferenceFromObject(oMinZ)
Set oPlane = oHybridShapeFactory.AddNewPlaneNormal(VZ, oReference)
oHybridBody.AppendHybridShape oPlane
oPlane.Name = "Bottom"
Set oBBSketchPlane = oPart.CreateReferenceFromObject(oPlane)
'vytvorime rovinu Top, ktera urci vysku BB
Set oReference = oPart.CreateReferenceFromObject(oMaxZ)
Set oBBTopPlane = oHybridShapeFactory.AddNewPlaneNormal(VZ, oReference)
oHybridBody.AppendHybridShape oBBTopPlane
oBBTopPlane.Name = "Top"
oPart.Update
V tomto momentě je připravené vše pro to, aby se mohlo začít se skicou, tvořící základnu BB. Velmi důležitým krokem je nastavení směru osového kříže u skicy. Pokud by se to neudělalo, osový kříž skicy by se nastavil podle absolutních souřadnic modelu.
'vytvorime skicu pro BB
Set oSketches = oBody.Sketches
Set oBBSketch = oSketches.Add(oBBSketchPlane)
'nastavime souradny system pro definici osoveho krize skicy
Dim CurrentAxisSystem(8)
CurrentAxisSystem(0) = CX
CurrentAxisSystem(1) = CY
CurrentAxisSystem(2) = CZ
CurrentAxisSystem(3) = VX1
CurrentAxisSystem(4) = VX2
CurrentAxisSystem(5) = VX3
CurrentAxisSystem(6) = VY1
CurrentAxisSystem(7) = VY2
CurrentAxisSystem(8) = VY3
oBBSketch.SetAbsoluteAxisData CurrentAxisSystem
'vytvorime skicu, pojmenujeme ji a nastavime instanci skicovacich prvku
Set factory2D1 = oBBSketch.OpenEdition()
oBBSketch.Name = "BBBase." & j
Set oBBSketchGeomeTry = oBBSketch.GeometricElements
'vyprojektujeme si body MinX, MaxX, MinY a MaxY Do skicy a projekce prejmenujeme na Projection1-4
Set oReference = oPart.CreateReferenceFromObject(oMinX)
Set oProjection = factory2D1.CreateProjections(oReference)
oBBSketchGeometry.Item("Mark.1").Name = "Projection1"
oBBSketchGeometry.Item("Projection1").Construction = True
Set oReference = oPart.CreateReferenceFromObject(oMaxX)
Set oProjection = factory2D1.CreateProjections(oReference)
oBBSketchGeometry.Item("Mark.1").Name = "Projection2"
oBBSketchGeometry.Item("Projection2").Construction = True
Set oReference = oPart.CreateReferenceFromObject(oMinY)
Set oProjection = factory2D1.CreateProjections(oReference)
oBBSketchGeometry.Item("Mark.1").Name = "Projection3"
oBBSketchGeometry.Item("Projection3").Construction = True
Set oReference = oPart.CreateReferenceFromObject(oMaxY)
Set oProjection = factory2D1.CreateProjections(oReference)
oBBSketchGeometry.Item("Mark.1").Name = "Projection4"
oBBSketchGeometry.Item("Projection4").Construction = True
'vytvorime ctverec 100x100
Set Corner1 = factory2D1.CreatePoint(0, 0)
Set Corner2 = factory2D1.CreatePoint(0, 100)
Set Corner3 = factory2D1.CreatePoint(100, 100)
Set Corner4 = factory2D1.CreatePoint(100, 0)
Set Edge1 = factory2D1.CreateLine(0, 0, 0, 100)
Edge1.StartPoint = Corner1
Edge1.EndPoint = Corner2
Set Edge2 = factory2D1.CreateLine(0, 100, 100, 100)
Edge2.StartPoint = Corner2
Edge2.EndPoint = Corner3
Set Edge3 = factory2D1.CreateLine(100, 100, 100, 0)
Edge3.StartPoint = Corner3
Edge3.EndPoint = Corner4
Set Edge4 = factory2D1.CreateLine(100, 0, 0, 0)
Edge4.StartPoint = Corner4
Edge4.EndPoint = Corner1
'vytvorime vazby mezi vyprojektovanymi body a hranami ctverce
'POZOR - kvuli poradi extremu vytvarime vazbu Projection3-Edge2 a Projection2-Edge3
Set oConstraints = oBBSketch.Constraints
Set CRef1 = oPart.CreateReferenceFromObject(oBBSketchGeometry.Item("Projection1"))
Set CRef2 = oPart.CreateReferenceFromObject(Edge1)
Set Constraint1 = oConstraints.AddBiEltCst(catCstTypeOn, CRef1, CRef2)
Constraint1.Mode = catCstModeDrivingDimension
Set CRef1 = oPart.CreateReferenceFromObject(oBBSketchGeometry.Item("Projection3"))
Set CRef2 = oPart.CreateReferenceFromObject(Edge2)
Set Constraint2 = oConstraints.AddBiEltCst(catCstTypeOn, CRef1, CRef2)
Constraint2.Mode = catCstModeDrivingDimension
Set CRef1 = oPart.CreateReferenceFromObject(oBBSketchGeometry.Item("Projection2"))
Set CRef2 = oPart.CreateReferenceFromObject(Edge3)
Set Constraint3 = oConstraints.AddBiEltCst(catCstTypeOn, CRef1, CRef2)
Constraint3.Mode = catCstModeDrivingDimension
Set CRef1 = oPart.CreateReferenceFromObject(oBBSketchGeometry.Item("Projection4"))
Set CRef2 = oPart.CreateReferenceFromObject(Edge4)
Set Constraint4 = oConstraints.AddBiEltCst(catCstTypeOn, CRef1, CRef2)
Constraint4.Mode = catCstModeDrivingDimension
'ukoncime skicar
oBBSketch.CloseEdition()
No a to už je skoro konec. V poslední části se vytvoří samotný Pad ze skicy a jeho výška se omezí rovinou "Top". Nakonec se Pad obarví na světle zeleno a nastaví se mu průhlednost, aby nezakrýval původní model.
'nastavime body BoundingBox jako aktivni
oPart.InWorkObject = oBody
'vytvorime pad ze skici s nulovou vyskou
Set oBB = oPart.ShapeFactory.AddNewPad (oBBSketch, 0)
'jako typ limitu nastavime "Up to plane"
Set oLimit = oBB.FirstLimit
oLimit.LimitMode = catUpToPlaneLimit
'limitni bude rovina "Top"
Set oReference = oPart.CreateReferenceFromObject(oBBTopPlane)
oLimit.LimitingElement = oReference
oBB.Name = "BoundingBox." & j
'obarvime BB nazeleno a nastavime mu pruhlednost
oSelection.Clear
oSelection.Add(oBody)
oSelection.VisProperties.SetRealColor 0,255,0,120
oSelection.visProperties.SetRealOpacity 150,1
oSelection.Visproperties.SetRealWidth 3,1
oSelection.Clear
'finalni update
oPart.Update
End Sub
Závěrem
Doufám, že jsem začínající Catia programátory neodradil, příště zkusím vybrat něco mnohem jednoduššího a budu se snažit i o podrobnější vysvětlení.Zkušenější z vás naopak vyzývám k zamyšlení, co by se v tomto makru dalo zlepšit. Jeden návrh na zlepšení bych měl hned teď. Na začátku by se určil jen směr lisování (Z) a ostatní by se dopočítaly automaticky tak, aby vznikl nejmenší možný objem BB (postupně natáčet osy x,y třeba po 1° a spočítat pro každou možnost objem - pak vytvořit BB v pozici s nejmenším objemem). Dalším vylepšením by mohl být zadávaní přídavků v jednotlivých směrech atd.