BIM: set up TestArchGui, clean up CLI/GUI tests
- Also update TechDraw templates path after reorganization from https://github.com/FreeCAD/FreeCAD/pull/23719
This commit is contained in:
@@ -202,9 +202,9 @@ SET(nativeifc_SRCS
|
||||
)
|
||||
|
||||
SET(bimtests_SRCS
|
||||
bimtests/TestArch.py
|
||||
bimtests/TestArchAxis.py
|
||||
bimtests/TestArchBase.py
|
||||
bimtests/TestArchBaseGui.py
|
||||
bimtests/TestArchComponent.py
|
||||
bimtests/TestArchBuildingPart.py
|
||||
bimtests/TestArchRoof.py
|
||||
@@ -214,6 +214,7 @@ SET(bimtests_SRCS
|
||||
bimtests/TestArchPanel.py
|
||||
bimtests/TestArchWindow.py
|
||||
bimtests/TestArchStairs.py
|
||||
bimtests/TestArchStructure.py
|
||||
bimtests/TestArchPipe.py
|
||||
bimtests/TestArchCurtainWall.py
|
||||
bimtests/TestArchProfile.py
|
||||
@@ -229,6 +230,8 @@ SET(bimtests_SRCS
|
||||
bimtests/TestArchTruss.py
|
||||
bimtests/TestWebGLExport.py
|
||||
bimtests/TestWebGLExportGui.py
|
||||
bimtests/TestArchImportersGui.py
|
||||
bimtests/TestArchBuildingPartGui.py
|
||||
)
|
||||
|
||||
SOURCE_GROUP("" FILES ${Arch_SRCS})
|
||||
|
||||
@@ -28,7 +28,7 @@ from bimtests.TestArchSpace import TestArchSpace
|
||||
from bimtests.TestArchWall import TestArchWall
|
||||
from bimtests.TestArchBuildingPart import TestArchBuildingPart
|
||||
from bimtests.TestArchAxis import TestArchAxis
|
||||
from bimtests.TestArch import TestArch
|
||||
from bimtests.TestArchStructure import TestArchStructure
|
||||
from bimtests.TestArchMaterial import TestArchMaterial
|
||||
from bimtests.TestArchPanel import TestArchPanel
|
||||
from bimtests.TestArchWindow import TestArchWindow
|
||||
|
||||
@@ -22,208 +22,8 @@
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
# Unit test for the Arch module
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import FreeCAD as App
|
||||
from FreeCAD import Units
|
||||
|
||||
import Arch
|
||||
import Draft
|
||||
import Part
|
||||
import Sketcher
|
||||
import TechDraw
|
||||
import WorkingPlane
|
||||
|
||||
from draftutils.messages import _msg
|
||||
|
||||
if App.GuiUp:
|
||||
import FreeCADGui
|
||||
"""Import all Arch module unit tests in GUI mode."""
|
||||
|
||||
from bimtests.TestArchImportersGui import TestArchImportersGui
|
||||
from bimtests.TestArchBuildingPartGui import TestArchBuildingPartGui
|
||||
from bimtests.TestWebGLExportGui import TestWebGLExportGui
|
||||
|
||||
class ArchTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
# setting a new document to hold the tests
|
||||
if App.ActiveDocument:
|
||||
if App.ActiveDocument.Name != "ArchTest":
|
||||
App.newDocument("ArchTest")
|
||||
else:
|
||||
App.newDocument("ArchTest")
|
||||
App.setActiveDocument("ArchTest")
|
||||
|
||||
def testRebar(self):
|
||||
App.Console.PrintLog ('Checking Arch Rebar…\n')
|
||||
s = Arch.makeStructure(length=2,width=3,height=5)
|
||||
sk = App.ActiveDocument.addObject('Sketcher::SketchObject','Sketch')
|
||||
sk.AttachmentSupport = (s,["Face6"])
|
||||
sk.addGeometry(Part.LineSegment(App.Vector(-0.85,1.25,0),App.Vector(0.75,1.25,0)))
|
||||
sk.addGeometry(Part.LineSegment(App.Vector(0.75,1.25,0),App.Vector(0.75,-1.20,0)))
|
||||
sk.addGeometry(Part.LineSegment(App.Vector(0.75,-1.20,0),App.Vector(-0.85,-1.20,0)))
|
||||
sk.addGeometry(Part.LineSegment(App.Vector(-0.85,-1.20,0),App.Vector(-0.85,1.25,0)))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident',0,2,1,1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident',1,2,2,1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident',2,2,3,1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident',3,2,0,1))
|
||||
r = Arch.makeRebar(s,sk,diameter=.1,amount=2)
|
||||
self.assertTrue(r,"Arch Rebar failed")
|
||||
|
||||
def testBuildingPart(self):
|
||||
"""Create a BuildingPart from a wall with a window and check its shape.
|
||||
"""
|
||||
# Also regression test for:
|
||||
# https://github.com/FreeCAD/FreeCAD/issues/6178
|
||||
operation = "Arch BuildingPart"
|
||||
_msg(" Test '{}'".format(operation))
|
||||
# Most of the code below taken from testWindow function.
|
||||
line = Draft.makeLine(App.Vector(0, 0, 0), App.Vector(3000, 0, 0))
|
||||
wall = Arch.makeWall(line)
|
||||
sk = App.ActiveDocument.addObject("Sketcher::SketchObject", "Sketch001")
|
||||
sk.Placement.Rotation = App.Rotation(App.Vector(1, 0, 0), 90)
|
||||
sk.addGeometry(Part.LineSegment(App.Vector( 500, 800, 0), App.Vector(1500, 800, 0)))
|
||||
sk.addGeometry(Part.LineSegment(App.Vector(1500, 800, 0), App.Vector(1500, 2000, 0)))
|
||||
sk.addGeometry(Part.LineSegment(App.Vector(1500, 2000, 0), App.Vector( 500, 2000, 0)))
|
||||
sk.addGeometry(Part.LineSegment(App.Vector( 500, 2000, 0), App.Vector( 500, 800, 0)))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 0, 2, 1, 1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 1, 2, 2, 1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 2, 2, 3, 1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 3, 2, 0, 1))
|
||||
App.ActiveDocument.recompute()
|
||||
win = Arch.makeWindow(sk)
|
||||
Arch.removeComponents(win, host=wall)
|
||||
App.ActiveDocument.recompute()
|
||||
bp = Arch.makeBuildingPart()
|
||||
|
||||
# Wall visibility works when standalone
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection('ArchTest',wall.Name)
|
||||
assert wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
App.ActiveDocument.recompute()
|
||||
assert not wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
assert wall.Visibility
|
||||
|
||||
bp.Group = [wall]
|
||||
App.ActiveDocument.recompute()
|
||||
# Fails with OCC 7.5
|
||||
# self.assertTrue(len(bp.Shape.Faces) == 16, "'{}' failed".format(operation))
|
||||
|
||||
# Wall visibility works when inside a BuildingPart
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
App.ActiveDocument.recompute()
|
||||
assert not wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
assert wall.Visibility
|
||||
|
||||
# Wall visibility works when BuildingPart Toggled
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection('ArchTest',bp.Name)
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
assert not wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
assert wall.Visibility
|
||||
|
||||
# Wall visibiity works inside group inside BuildingPart Toggled
|
||||
grp = App.ActiveDocument.addObject("App::DocumentObjectGroup","Group")
|
||||
grp.Label="Group"
|
||||
grp.Group = [wall]
|
||||
bp.Group = [grp]
|
||||
App.ActiveDocument.recompute()
|
||||
assert wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
App.ActiveDocument.recompute()
|
||||
assert not wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
App.ActiveDocument.recompute()
|
||||
assert wall.Visibility
|
||||
|
||||
def testImportSH3D(self):
|
||||
"""Import a SweetHome 3D file
|
||||
"""
|
||||
operation = "importers.importSH3D"
|
||||
_msg(" Test '{}'".format(operation))
|
||||
import BIM.importers.importSH3DHelper
|
||||
importer = BIM.importers.importSH3DHelper.SH3DImporter(None)
|
||||
importer.import_sh3d_from_string(SH3D_HOME)
|
||||
assert App.ActiveDocument.Site
|
||||
assert App.ActiveDocument.BuildingPart.Label == "Building"
|
||||
assert App.ActiveDocument.BuildingPart001.Label == "Level"
|
||||
assert App.ActiveDocument.Wall
|
||||
|
||||
def tearDown(self):
|
||||
App.closeDocument("ArchTest")
|
||||
pass
|
||||
|
||||
|
||||
SH3D_HOME = """<?xml version='1.0'?>
|
||||
<home version='7200' name='0-JoinWall.sh3d' camera='topCamera' wallHeight='250.0'>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.CatalogPaneDividerLocation' value='327'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.ColumnWidths' value='100,84,82,85,84'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.FrameHeight' value='576'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.FrameMaximized' value='true'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.FrameWidth' value='1092'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.FrameX' value='50'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.FrameY' value='87'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.MainPaneDividerLocation' value='441'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.PlanPaneDividerLocation' value='263'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.PlanScale' value='0.21343713'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.PlanViewportX' value='0'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.PlanViewportY' value='0'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.ScreenHeight' value='720'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.ScreenWidth' value='1366'/>
|
||||
<furnitureVisibleProperty name='NAME'/>
|
||||
<furnitureVisibleProperty name='WIDTH'/>
|
||||
<furnitureVisibleProperty name='DEPTH'/>
|
||||
<furnitureVisibleProperty name='HEIGHT'/>
|
||||
<furnitureVisibleProperty name='VISIBLE'/>
|
||||
<environment groundColor='FFB78744' skyColor='00CCE4FC' lightColor='00D0D0D0' ceillingLightColor='00D0D0D0' photoWidth='400' photoHeight='300' photoAspectRatio='VIEW_3D_RATIO' photoQuality='0' videoWidth='320' videoAspectRatio='RATIO_4_3' videoQuality='0' videoFrameRate='25'>
|
||||
<texture attribute='skyTexture' name='Cloudy' creator='eTeks' catalogId='eTeks#cloudy' width='100.0' height='27.6' image='0'/>
|
||||
</environment>
|
||||
<compass x='-100.0' y='50.0' diameter='100.0' northDirection='0.0' longitude='-0.06428629' latitude='0.70511305' timeZone='Europe/Madrid'/>
|
||||
<observerCamera attribute='observerCamera' lens='PINHOLE' x='50.0' y='50.0' z='170.0' yaw='5.4977875' pitch='0.19634955' fieldOfView='1.0995575' time='1729080000000'/>
|
||||
<camera attribute='topCamera' lens='PINHOLE' x='1304.082' y='1936.5889' z='1526.6199' yaw='8.98363' pitch='0.7049999' fieldOfView='1.0995575' time='1729080000000'/>
|
||||
<wall id='wall0' wallAtEnd='wall1' xStart='0.0' yStart='0.0' xEnd='100.0' yEnd='0.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall1' wallAtStart='wall0' wallAtEnd='wall2' xStart='100.0' yStart='0.0' xEnd='200.0' yEnd='0.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall2' wallAtStart='wall1' xStart='200.0' yStart='0.0' xEnd='300.0' yEnd='0.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall3' wallAtEnd='wall4' xStart='0.0' yStart='50.0' xEnd='100.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall4' wallAtStart='wall3' wallAtEnd='wall5' xStart='100.0' yStart='100.0' xEnd='200.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall5' wallAtStart='wall4' xStart='200.0' yStart='100.0' xEnd='300.0' yEnd='50.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall6' wallAtEnd='wall7' xStart='0.0' yStart='200.0' xEnd='100.0' yEnd='300.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall7' wallAtStart='wall6' wallAtEnd='wall8' xStart='100.0' yStart='300.0' xEnd='200.0' yEnd='300.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall8' wallAtStart='wall7' xStart='200.0' yStart='300.0' xEnd='300.0' yEnd='200.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall9' wallAtEnd='wall10' xStart='100.0' yStart='400.0' xEnd='100.0' yEnd='500.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall10' wallAtStart='wall9' wallAtEnd='wall11' xStart='100.0' yStart='500.0' xEnd='200.0' yEnd='500.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall11' wallAtStart='wall10' xStart='200.0' yStart='500.0' xEnd='200.0' yEnd='400.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall12' wallAtStart='wall14' wallAtEnd='wall13' xStart='150.0' yStart='600.0' xEnd='100.0' yEnd='700.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall13' wallAtStart='wall12' wallAtEnd='wall14' xStart='100.0' yStart='700.0' xEnd='200.0' yEnd='700.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall14' wallAtStart='wall13' wallAtEnd='wall12' xStart='200.0' yStart='700.0' xEnd='150.0' yEnd='600.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall15' wallAtEnd='wall16' xStart='400.0' yStart='150.0' xEnd='500.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall16' wallAtStart='wall15' wallAtEnd='wall17' xStart='500.0' yStart='100.0' xEnd='600.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall17' wallAtStart='wall16' xStart='600.0' yStart='100.0' xEnd='700.0' yEnd='50.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall18' wallAtEnd='wall19' xStart='400.0' yStart='400.0' xEnd='500.0' yEnd='300.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall19' wallAtStart='wall18' wallAtEnd='wall20' xStart='500.0' yStart='300.0' xEnd='600.0' yEnd='300.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall20' wallAtStart='wall19' xStart='600.0' yStart='300.0' xEnd='700.0' yEnd='200.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall21' wallAtEnd='wall22' xStart='400.0' yStart='600.0' xEnd='400.0' yEnd='500.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall22' wallAtStart='wall21' wallAtEnd='wall23' xStart='400.0' yStart='500.0' xEnd='600.0' yEnd='500.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall23' wallAtStart='wall22' xStart='600.0' yStart='500.0' xEnd='600.0' yEnd='400.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall24' wallAtEnd='wall25' xStart='600.0' yStart='800.0' xEnd='500.0' yEnd='700.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall25' wallAtStart='wall24' wallAtEnd='wall26' xStart='500.0' yStart='700.0' xEnd='600.0' yEnd='700.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall26' wallAtStart='wall25' xStart='600.0' yStart='700.0' xEnd='500.0' yEnd='600.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall27' wallAtStart='wall30' wallAtEnd='wall28' xStart='800.0' yStart='0.0' xEnd='1000.0' yEnd='0.0' height='250.0' thickness='10.0' arcExtent='1.0471976' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall28' wallAtStart='wall27' wallAtEnd='wall29' xStart='1000.0' yStart='0.0' xEnd='1000.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall29' wallAtStart='wall28' wallAtEnd='wall30' xStart='1000.0' yStart='100.0' xEnd='800.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall30' wallAtStart='wall29' wallAtEnd='wall27' xStart='800.0' yStart='100.0' xEnd='800.0' yEnd='0.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall31' wallAtEnd='wall32' xStart='800.0' yStart='400.0' xEnd='1000.0' yEnd='200.0' height='250.0' thickness='10.0' arcExtent='1.5707964' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall32' wallAtStart='wall31' wallAtEnd='wall33' xStart='1000.0' yStart='200.0' xEnd='1200.0' yEnd='400.0' height='250.0' thickness='10.0' arcExtent='1.5707964' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall33' wallAtStart='wall32' wallAtEnd='wall34' xStart='1200.0' yStart='400.0' xEnd='1000.0' yEnd='600.0' height='250.0' thickness='10.0' arcExtent='1.5707964' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall34' wallAtStart='wall33' xStart='1000.0' yStart='600.0' xEnd='800.0' yEnd='400.0' height='250.0' thickness='10.0' arcExtent='1.5707964' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall35' wallAtEnd='wall36' xStart='800.0' yStart='800.0' xEnd='900.0' yEnd='900.0' height='250.0' thickness='10.0' arcExtent='-3.1415927' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall36' wallAtStart='wall35' wallAtEnd='wall37' xStart='900.0' yStart='900.0' xEnd='1000.0' yEnd='800.0' height='250.0' thickness='10.0' arcExtent='-3.1415927' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall37' wallAtStart='wall36' wallAtEnd='wall38' xStart='1000.0' yStart='800.0' xEnd='900.0' yEnd='700.0' height='250.0' thickness='10.0' arcExtent='-3.1415927' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall38' wallAtStart='wall37' xStart='900.0' yStart='700.0' xEnd='800.0' yEnd='800.0' height='250.0' thickness='10.0' arcExtent='-3.1415927' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
</home>
|
||||
"""
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2013 Yorik van Havre <yorik@uncreated.net> *
|
||||
# * Copyright (c) 2025 Furgo *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * FreeCAD 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import os
|
||||
import FreeCAD as App
|
||||
import Arch
|
||||
import Draft
|
||||
import Part
|
||||
import Sketcher
|
||||
import Arch
|
||||
from bimtests import TestArchBase
|
||||
from draftutils.messages import _msg
|
||||
|
||||
# TODO: move these tests to their relevant modules, remove this file
|
||||
class TestArch(TestArchBase.TestArchBase):
|
||||
|
||||
def testStructure(self):
|
||||
App.Console.PrintLog ('Checking BIM Structure...\n')
|
||||
s = Arch.makeStructure(length=2,width=3,height=5)
|
||||
self.assertTrue(s,"BIM Structure failed")
|
||||
|
||||
def testAxis(self):
|
||||
App.Console.PrintLog ('Checking Arch Axis...\n')
|
||||
a = Arch.makeAxis()
|
||||
self.assertTrue(a,"Arch Axis failed")
|
||||
|
||||
def testSection(self):
|
||||
App.Console.PrintLog ('Checking Arch Section...\n')
|
||||
s = Arch.makeSectionPlane([])
|
||||
self.assertTrue(s,"Arch Section failed")
|
||||
|
||||
def testStairs(self):
|
||||
App.Console.PrintLog ('Checking Arch Stairs...\n')
|
||||
s = Arch.makeStairs()
|
||||
self.assertTrue(s,"Arch Stairs failed")
|
||||
|
||||
def testFrame(self):
|
||||
App.Console.PrintLog ('Checking Arch Frame...\n')
|
||||
l=Draft.makeLine(App.Vector(0,0,0),App.Vector(-2,0,0))
|
||||
p = Draft.makeRectangle(length=.5,height=.5)
|
||||
f = Arch.makeFrame(l,p)
|
||||
self.assertTrue(f,"Arch Frame failed")
|
||||
|
||||
def testEquipment(self):
|
||||
App.Console.PrintLog ('Checking Arch Equipment...\n')
|
||||
box = App.ActiveDocument.addObject("Part::Box", "Box")
|
||||
box.Length = 500
|
||||
box.Width = 2000
|
||||
box.Height = 600
|
||||
equip = Arch.makeEquipment(box)
|
||||
self.assertTrue(equip,"Arch Equipment failed")
|
||||
|
||||
def testPipe(self):
|
||||
App.Console.PrintLog ('Checking Arch Pipe...\n')
|
||||
pipe = Arch.makePipe(diameter=120, length=3000)
|
||||
self.assertTrue(pipe,"Arch Pipe failed")
|
||||
|
||||
def testAdd(self):
|
||||
App.Console.PrintLog ('Checking Arch Add...\n')
|
||||
l=Draft.makeLine(App.Vector(0,0,0),App.Vector(2,0,0))
|
||||
w = Arch.makeWall(l,width=0.2,height=2)
|
||||
sb = Part.makeBox(1,1,1)
|
||||
b = App.ActiveDocument.addObject('Part::Feature','Box')
|
||||
b.Shape = sb
|
||||
App.ActiveDocument.recompute()
|
||||
Arch.addComponents(b,w)
|
||||
App.ActiveDocument.recompute()
|
||||
r = (w.Shape.Volume > 1.5)
|
||||
self.assertTrue(r,"Arch Add failed")
|
||||
|
||||
def testRemove(self):
|
||||
App.Console.PrintLog ('Checking Arch Remove...\n')
|
||||
l=Draft.makeLine(App.Vector(0,0,0),App.Vector(2,0,0))
|
||||
w = Arch.makeWall(l,width=0.2,height=2,align="Right")
|
||||
sb = Part.makeBox(1,1,1)
|
||||
b = App.ActiveDocument.addObject('Part::Feature','Box')
|
||||
b.Shape = sb
|
||||
App.ActiveDocument.recompute()
|
||||
Arch.removeComponents(b,w)
|
||||
App.ActiveDocument.recompute()
|
||||
r = (w.Shape.Volume < 0.75)
|
||||
self.assertTrue(r,"Arch Remove failed")
|
||||
|
||||
def testViewGeneration(self):
|
||||
"""Tests the whole TD view generation workflow"""
|
||||
|
||||
operation = "View generation"
|
||||
_msg(" Test '{}'".format(operation))
|
||||
|
||||
# Create a few objects
|
||||
points = [App.Vector(0.0, 0.0, 0.0), App.Vector(2000.0, 0.0, 0.0)]
|
||||
line = Draft.make_wire(points)
|
||||
wall = Arch.makeWall(line, height=2000)
|
||||
wpl = App.Placement(App.Vector(500,0,1500), App.Vector(1,0,0),-90)
|
||||
win = Arch.makeWindowPreset('Fixed', width=1000.0, height=1000.0, h1=50.0, h2=50.0, h3=50.0, w1=100.0, w2=50.0, o1=0.0, o2=50.0, placement=wpl)
|
||||
win.Hosts = [wall]
|
||||
profile = Arch.makeProfile([169, 'HEA', 'HEA100', 'H', 100.0, 96.0, 5.0, 8.0])
|
||||
column = Arch.makeStructure(profile, height=2000.0)
|
||||
column.Profile = "HEA100"
|
||||
column.Placement.Base = App.Vector(500.0, 600.0, 0.0)
|
||||
level = Arch.makeFloor()
|
||||
level.addObjects([wall, column])
|
||||
App.ActiveDocument.recompute()
|
||||
|
||||
# Create a drawing view
|
||||
section = Arch.makeSectionPlane(level)
|
||||
drawing = Arch.make2DDrawing()
|
||||
view = Draft.make_shape2dview(section)
|
||||
cut = Draft.make_shape2dview(section)
|
||||
cut.InPlace = False
|
||||
cut.ProjectionMode = "Cutfaces"
|
||||
drawing.addObjects([view, cut])
|
||||
App.ActiveDocument.recompute()
|
||||
|
||||
# Create a TD page
|
||||
tpath = os.path.join(App.getResourceDir(),"Mod","TechDraw","Templates","ISO","A3_Landscape_blank.svg")
|
||||
page = App.ActiveDocument.addObject("TechDraw::DrawPage", "Page")
|
||||
template = App.ActiveDocument.addObject("TechDraw::DrawSVGTemplate", "Template")
|
||||
template.Template = tpath
|
||||
page.Template = template
|
||||
view = App.ActiveDocument.addObject("TechDraw::DrawViewDraft", "DraftView")
|
||||
view.Source = drawing
|
||||
page.addView(view)
|
||||
view.Scale = 1.0
|
||||
view.X = "20cm"
|
||||
view.Y = "15cm"
|
||||
App.ActiveDocument.recompute()
|
||||
assert True
|
||||
@@ -30,11 +30,35 @@ import FreeCAD
|
||||
class TestArchBase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
print(f"Initializing: {self.__class__.__name__}")
|
||||
self.document = FreeCAD.newDocument(self.__class__.__name__)
|
||||
"""
|
||||
Set up a new, clean document for the test. Ensure test isolation by creating a
|
||||
uniquely-named document and cleaning up any potential leftovers from a previously failed
|
||||
run.
|
||||
"""
|
||||
self.doc_name = self.__class__.__name__
|
||||
|
||||
# Close any document of the same name that might have been left over from a crashed or
|
||||
# aborted test run. FreeCAD.getDocument() raises a NameError if the document is not found,
|
||||
# so we wrap this check in a try...except block.
|
||||
try:
|
||||
FreeCAD.getDocument(self.doc_name)
|
||||
# If getDocument() succeeds, the document exists and must be closed.
|
||||
FreeCAD.closeDocument(self.doc_name)
|
||||
except NameError:
|
||||
# This is the expected path on a clean run; do nothing.
|
||||
pass
|
||||
|
||||
# Create a fresh document for the current test.
|
||||
self.document = FreeCAD.newDocument(self.doc_name)
|
||||
self.assertEqual(self.document.Name, self.doc_name)
|
||||
|
||||
def tearDown(self):
|
||||
FreeCAD.closeDocument(self.document.Name)
|
||||
"""Close the test document after all tests in the class are complete."""
|
||||
if hasattr(self, 'document') and self.document:
|
||||
try:
|
||||
FreeCAD.closeDocument(self.document.Name)
|
||||
except Exception as e:
|
||||
FreeCAD.Console.PrintError(f"Error during tearDown in {self.__class__.__name__}: {e}\n")
|
||||
|
||||
def printTestMessage(self, text, prepend_text="Test ", end="\n"):
|
||||
"""Write messages to the console including the line ending.
|
||||
@@ -43,3 +67,4 @@ class TestArchBase(unittest.TestCase):
|
||||
passed as the prepend_text argument
|
||||
"""
|
||||
FreeCAD.Console.PrintMessage(prepend_text + text + end)
|
||||
|
||||
|
||||
55
src/Mod/BIM/bimtests/TestArchBaseGui.py
Normal file
55
src/Mod/BIM/bimtests/TestArchBaseGui.py
Normal file
@@ -0,0 +1,55 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2025 Furgo *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * FreeCAD 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import unittest
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from bimtests.TestArchBase import TestArchBase
|
||||
|
||||
class TestArchBaseGui(TestArchBase):
|
||||
"""
|
||||
The base class for all Arch/BIM GUI unit tests.
|
||||
It inherits from TestArchBase to handle document setup and adds
|
||||
GUI-specific initialization by activating the BIM workbench.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""
|
||||
Ensure the GUI is available and activate the BIM workbench once
|
||||
before any tests in the inheriting class are run.
|
||||
"""
|
||||
if not FreeCAD.GuiUp:
|
||||
raise unittest.SkipTest("Cannot run GUI tests in a CLI environment.")
|
||||
|
||||
# Activating the workbench ensures all GUI commands are loaded and ready.
|
||||
FreeCADGui.activateWorkbench("BIMWorkbench")
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Run the parent's setup to create the uniquely named document.
|
||||
The workbench is already activated by setUpClass.
|
||||
"""
|
||||
super().setUp()
|
||||
|
||||
79
src/Mod/BIM/bimtests/TestArchBuildingPartGui.py
Normal file
79
src/Mod/BIM/bimtests/TestArchBuildingPartGui.py
Normal file
@@ -0,0 +1,79 @@
|
||||
import FreeCAD as App
|
||||
import FreeCADGui
|
||||
import Arch
|
||||
import Draft
|
||||
import Part
|
||||
import Sketcher
|
||||
from bimtests.TestArchBaseGui import TestArchBaseGui
|
||||
|
||||
class TestArchBuildingPartGui(TestArchBaseGui):
|
||||
|
||||
def testBuildingPart(self):
|
||||
"""Create a BuildingPart from a wall with a window and check its shape.
|
||||
"""
|
||||
# Also regression test for:
|
||||
# https://github.com/FreeCAD/FreeCAD/issues/6178
|
||||
#operation = "Arch BuildingPart"
|
||||
#_msg(" Test '{}'".format(operation))
|
||||
# Most of the code below taken from testWindow function.
|
||||
line = Draft.makeLine(App.Vector(0, 0, 0), App.Vector(3000, 0, 0))
|
||||
wall = Arch.makeWall(line)
|
||||
sk = App.ActiveDocument.addObject("Sketcher::SketchObject", "Sketch001")
|
||||
sk.Placement.Rotation = App.Rotation(App.Vector(1, 0, 0), 90)
|
||||
sk.addGeometry(Part.LineSegment(App.Vector( 500, 800, 0), App.Vector(1500, 800, 0)))
|
||||
sk.addGeometry(Part.LineSegment(App.Vector(1500, 800, 0), App.Vector(1500, 2000, 0)))
|
||||
sk.addGeometry(Part.LineSegment(App.Vector(1500, 2000, 0), App.Vector( 500, 2000, 0)))
|
||||
sk.addGeometry(Part.LineSegment(App.Vector( 500, 2000, 0), App.Vector( 500, 800, 0)))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 0, 2, 1, 1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 1, 2, 2, 1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 2, 2, 3, 1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 3, 2, 0, 1))
|
||||
App.ActiveDocument.recompute()
|
||||
win = Arch.makeWindow(sk)
|
||||
Arch.removeComponents(win, host=wall)
|
||||
App.ActiveDocument.recompute()
|
||||
bp = Arch.makeBuildingPart()
|
||||
|
||||
# Wall visibility works when standalone
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection(self.doc_name,wall.Name)
|
||||
assert wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
App.ActiveDocument.recompute()
|
||||
assert not wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
assert wall.Visibility
|
||||
|
||||
bp.Group = [wall]
|
||||
App.ActiveDocument.recompute()
|
||||
# Fails with OCC 7.5
|
||||
# self.assertTrue(len(bp.Shape.Faces) == 16, "'{}' failed".format(operation))
|
||||
|
||||
# Wall visibility works when inside a BuildingPart
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
App.ActiveDocument.recompute()
|
||||
assert not wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
assert wall.Visibility
|
||||
|
||||
# Wall visibility works when BuildingPart Toggled
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection(self.doc_name,bp.Name)
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
assert not wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
assert wall.Visibility
|
||||
|
||||
# Wall visibiity works inside group inside BuildingPart Toggled
|
||||
grp = App.ActiveDocument.addObject("App::DocumentObjectGroup","Group")
|
||||
grp.Label="Group"
|
||||
grp.Group = [wall]
|
||||
bp.Group = [grp]
|
||||
App.ActiveDocument.recompute()
|
||||
assert wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
App.ActiveDocument.recompute()
|
||||
assert not wall.Visibility
|
||||
FreeCADGui.runCommand('Std_ToggleVisibility',0)
|
||||
App.ActiveDocument.recompute()
|
||||
assert wall.Visibility
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
import Arch
|
||||
import Draft
|
||||
import Part
|
||||
import FreeCAD as App
|
||||
from bimtests import TestArchBase
|
||||
from draftutils.messages import _msg
|
||||
@@ -34,6 +35,32 @@ from math import pi, cos, sin, radians
|
||||
|
||||
class TestArchComponent(TestArchBase.TestArchBase):
|
||||
|
||||
def testAdd(self):
|
||||
App.Console.PrintLog ('Checking Arch Add...\n')
|
||||
l=Draft.makeLine(App.Vector(0,0,0),App.Vector(2,0,0))
|
||||
w = Arch.makeWall(l,width=0.2,height=2)
|
||||
sb = Part.makeBox(1,1,1)
|
||||
b = App.ActiveDocument.addObject('Part::Feature','Box')
|
||||
b.Shape = sb
|
||||
App.ActiveDocument.recompute()
|
||||
Arch.addComponents(b,w)
|
||||
App.ActiveDocument.recompute()
|
||||
r = (w.Shape.Volume > 1.5)
|
||||
self.assertTrue(r,"Arch Add failed")
|
||||
|
||||
def testRemove(self):
|
||||
App.Console.PrintLog ('Checking Arch Remove...\n')
|
||||
l=Draft.makeLine(App.Vector(0,0,0),App.Vector(2,0,0))
|
||||
w = Arch.makeWall(l,width=0.2,height=2,align="Right")
|
||||
sb = Part.makeBox(1,1,1)
|
||||
b = App.ActiveDocument.addObject('Part::Feature','Box')
|
||||
b.Shape = sb
|
||||
App.ActiveDocument.recompute()
|
||||
Arch.removeComponents(b,w)
|
||||
App.ActiveDocument.recompute()
|
||||
r = (w.Shape.Volume < 0.75)
|
||||
self.assertTrue(r,"Arch Remove failed")
|
||||
|
||||
def testBsplineSlabAreas(self):
|
||||
"""Test the HorizontalArea and VerticalArea properties of a Bspline-based slab.
|
||||
|
||||
|
||||
@@ -23,15 +23,22 @@
|
||||
# ***************************************************************************
|
||||
|
||||
import Arch
|
||||
import FreeCAD as App
|
||||
from bimtests import TestArchBase
|
||||
|
||||
class TestArchEquipment(TestArchBase.TestArchBase):
|
||||
|
||||
def test_makeEquipment(self):
|
||||
"""Test the makeEquipment function."""
|
||||
operation = "Testing makeEquipment..."
|
||||
self.printTestMessage(operation)
|
||||
|
||||
obj = Arch.makeEquipment()
|
||||
self.assertIsNotNone(obj, "makeEquipment failed to create an object")
|
||||
self.assertEqual(obj.Label, "Equipment", "Incorrect default label for Equipment")
|
||||
self.assertEqual(obj.Label, "Equipment", "Incorrect default label for Equipment")
|
||||
|
||||
def testEquipment(self):
|
||||
box = App.ActiveDocument.addObject("Part::Box", "Box")
|
||||
box.Length = 500
|
||||
box.Width = 2000
|
||||
box.Height = 600
|
||||
equip = Arch.makeEquipment(box)
|
||||
self.assertTrue(equip,"Arch Equipment failed")
|
||||
@@ -23,15 +23,21 @@
|
||||
# ***************************************************************************
|
||||
|
||||
import Arch
|
||||
import Draft
|
||||
import FreeCAD as App
|
||||
from bimtests import TestArchBase
|
||||
|
||||
class TestArchFrame(TestArchBase.TestArchBase):
|
||||
|
||||
def test_makeFrame(self):
|
||||
"""Test the makeFrame function."""
|
||||
operation = "Testing makeFrame..."
|
||||
self.printTestMessage(operation)
|
||||
|
||||
obj = Arch.makeFrame(None, None)
|
||||
self.assertIsNotNone(obj, "makeFrame failed to create an object")
|
||||
self.assertEqual(obj.Label, "Frame", "Incorrect default label for Frame")
|
||||
self.assertEqual(obj.Label, "Frame", "Incorrect default label for Frame")
|
||||
|
||||
def testFrame(self):
|
||||
l=Draft.makeLine(App.Vector(0,0,0),App.Vector(-2,0,0))
|
||||
p = Draft.makeRectangle(length=.5,height=.5)
|
||||
f = Arch.makeFrame(l,p)
|
||||
self.assertTrue(f,"Arch Frame failed")
|
||||
88
src/Mod/BIM/bimtests/TestArchImportersGui.py
Normal file
88
src/Mod/BIM/bimtests/TestArchImportersGui.py
Normal file
@@ -0,0 +1,88 @@
|
||||
|
||||
import FreeCAD as App
|
||||
from bimtests.TestArchBaseGui import TestArchBaseGui
|
||||
|
||||
class TestArchImportersGui(TestArchBaseGui):
|
||||
|
||||
def testImportSH3D(self):
|
||||
"""Import a SweetHome 3D file
|
||||
"""
|
||||
import BIM.importers.importSH3DHelper
|
||||
|
||||
importer = BIM.importers.importSH3DHelper.SH3DImporter(None)
|
||||
importer.import_sh3d_from_string(SH3D_HOME)
|
||||
|
||||
assert App.ActiveDocument.Site
|
||||
assert App.ActiveDocument.BuildingPart.Label == "Building"
|
||||
assert App.ActiveDocument.BuildingPart001.Label == "Level"
|
||||
assert App.ActiveDocument.Wall
|
||||
|
||||
|
||||
SH3D_HOME = """<?xml version='1.0'?>
|
||||
<home version='7200' name='0-JoinWall.sh3d' camera='topCamera' wallHeight='250.0'>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.CatalogPaneDividerLocation' value='327'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.ColumnWidths' value='100,84,82,85,84'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.FrameHeight' value='576'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.FrameMaximized' value='true'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.FrameWidth' value='1092'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.FrameX' value='50'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.FrameY' value='87'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.MainPaneDividerLocation' value='441'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.PlanPaneDividerLocation' value='263'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.PlanScale' value='0.21343713'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.PlanViewportX' value='0'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.PlanViewportY' value='0'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.ScreenHeight' value='720'/>
|
||||
<property name='com.eteks.sweethome3d.SweetHome3D.ScreenWidth' value='1366'/>
|
||||
<furnitureVisibleProperty name='NAME'/>
|
||||
<furnitureVisibleProperty name='WIDTH'/>
|
||||
<furnitureVisibleProperty name='DEPTH'/>
|
||||
<furnitureVisibleProperty name='HEIGHT'/>
|
||||
<furnitureVisibleProperty name='VISIBLE'/>
|
||||
<environment groundColor='FFB78744' skyColor='00CCE4FC' lightColor='00D0D0D0' ceillingLightColor='00D0D0D0' photoWidth='400' photoHeight='300' photoAspectRatio='VIEW_3D_RATIO' photoQuality='0' videoWidth='320' videoAspectRatio='RATIO_4_3' videoQuality='0' videoFrameRate='25'>
|
||||
<texture attribute='skyTexture' name='Cloudy' creator='eTeks' catalogId='eTeks#cloudy' width='100.0' height='27.6' image='0'/>
|
||||
</environment>
|
||||
<compass x='-100.0' y='50.0' diameter='100.0' northDirection='0.0' longitude='-0.06428629' latitude='0.70511305' timeZone='Europe/Madrid'/>
|
||||
<observerCamera attribute='observerCamera' lens='PINHOLE' x='50.0' y='50.0' z='170.0' yaw='5.4977875' pitch='0.19634955' fieldOfView='1.0995575' time='1729080000000'/>
|
||||
<camera attribute='topCamera' lens='PINHOLE' x='1304.082' y='1936.5889' z='1526.6199' yaw='8.98363' pitch='0.7049999' fieldOfView='1.0995575' time='1729080000000'/>
|
||||
<wall id='wall0' wallAtEnd='wall1' xStart='0.0' yStart='0.0' xEnd='100.0' yEnd='0.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall1' wallAtStart='wall0' wallAtEnd='wall2' xStart='100.0' yStart='0.0' xEnd='200.0' yEnd='0.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall2' wallAtStart='wall1' xStart='200.0' yStart='0.0' xEnd='300.0' yEnd='0.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall3' wallAtEnd='wall4' xStart='0.0' yStart='50.0' xEnd='100.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall4' wallAtStart='wall3' wallAtEnd='wall5' xStart='100.0' yStart='100.0' xEnd='200.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall5' wallAtStart='wall4' xStart='200.0' yStart='100.0' xEnd='300.0' yEnd='50.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall6' wallAtEnd='wall7' xStart='0.0' yStart='200.0' xEnd='100.0' yEnd='300.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall7' wallAtStart='wall6' wallAtEnd='wall8' xStart='100.0' yStart='300.0' xEnd='200.0' yEnd='300.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall8' wallAtStart='wall7' xStart='200.0' yStart='300.0' xEnd='300.0' yEnd='200.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall9' wallAtEnd='wall10' xStart='100.0' yStart='400.0' xEnd='100.0' yEnd='500.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall10' wallAtStart='wall9' wallAtEnd='wall11' xStart='100.0' yStart='500.0' xEnd='200.0' yEnd='500.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall11' wallAtStart='wall10' xStart='200.0' yStart='500.0' xEnd='200.0' yEnd='400.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall12' wallAtStart='wall14' wallAtEnd='wall13' xStart='150.0' yStart='600.0' xEnd='100.0' yEnd='700.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall13' wallAtStart='wall12' wallAtEnd='wall14' xStart='100.0' yStart='700.0' xEnd='200.0' yEnd='700.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall14' wallAtStart='wall13' wallAtEnd='wall12' xStart='200.0' yStart='700.0' xEnd='150.0' yEnd='600.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall15' wallAtEnd='wall16' xStart='400.0' yStart='150.0' xEnd='500.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall16' wallAtStart='wall15' wallAtEnd='wall17' xStart='500.0' yStart='100.0' xEnd='600.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall17' wallAtStart='wall16' xStart='600.0' yStart='100.0' xEnd='700.0' yEnd='50.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall18' wallAtEnd='wall19' xStart='400.0' yStart='400.0' xEnd='500.0' yEnd='300.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall19' wallAtStart='wall18' wallAtEnd='wall20' xStart='500.0' yStart='300.0' xEnd='600.0' yEnd='300.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall20' wallAtStart='wall19' xStart='600.0' yStart='300.0' xEnd='700.0' yEnd='200.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall21' wallAtEnd='wall22' xStart='400.0' yStart='600.0' xEnd='400.0' yEnd='500.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall22' wallAtStart='wall21' wallAtEnd='wall23' xStart='400.0' yStart='500.0' xEnd='600.0' yEnd='500.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall23' wallAtStart='wall22' xStart='600.0' yStart='500.0' xEnd='600.0' yEnd='400.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall24' wallAtEnd='wall25' xStart='600.0' yStart='800.0' xEnd='500.0' yEnd='700.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall25' wallAtStart='wall24' wallAtEnd='wall26' xStart='500.0' yStart='700.0' xEnd='600.0' yEnd='700.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall26' wallAtStart='wall25' xStart='600.0' yStart='700.0' xEnd='500.0' yEnd='600.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall27' wallAtStart='wall30' wallAtEnd='wall28' xStart='800.0' yStart='0.0' xEnd='1000.0' yEnd='0.0' height='250.0' thickness='10.0' arcExtent='1.0471976' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall28' wallAtStart='wall27' wallAtEnd='wall29' xStart='1000.0' yStart='0.0' xEnd='1000.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall29' wallAtStart='wall28' wallAtEnd='wall30' xStart='1000.0' yStart='100.0' xEnd='800.0' yEnd='100.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall30' wallAtStart='wall29' wallAtEnd='wall27' xStart='800.0' yStart='100.0' xEnd='800.0' yEnd='0.0' height='250.0' thickness='10.0' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall31' wallAtEnd='wall32' xStart='800.0' yStart='400.0' xEnd='1000.0' yEnd='200.0' height='250.0' thickness='10.0' arcExtent='1.5707964' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall32' wallAtStart='wall31' wallAtEnd='wall33' xStart='1000.0' yStart='200.0' xEnd='1200.0' yEnd='400.0' height='250.0' thickness='10.0' arcExtent='1.5707964' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall33' wallAtStart='wall32' wallAtEnd='wall34' xStart='1200.0' yStart='400.0' xEnd='1000.0' yEnd='600.0' height='250.0' thickness='10.0' arcExtent='1.5707964' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall34' wallAtStart='wall33' xStart='1000.0' yStart='600.0' xEnd='800.0' yEnd='400.0' height='250.0' thickness='10.0' arcExtent='1.5707964' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall35' wallAtEnd='wall36' xStart='800.0' yStart='800.0' xEnd='900.0' yEnd='900.0' height='250.0' thickness='10.0' arcExtent='-3.1415927' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall36' wallAtStart='wall35' wallAtEnd='wall37' xStart='900.0' yStart='900.0' xEnd='1000.0' yEnd='800.0' height='250.0' thickness='10.0' arcExtent='-3.1415927' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall37' wallAtStart='wall36' wallAtEnd='wall38' xStart='1000.0' yStart='800.0' xEnd='900.0' yEnd='700.0' height='250.0' thickness='10.0' arcExtent='-3.1415927' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
<wall id='wall38' wallAtStart='wall37' xStart='900.0' yStart='700.0' xEnd='800.0' yEnd='800.0' height='250.0' thickness='10.0' arcExtent='-3.1415927' pattern='hatchUp' topColor='FF0000FF' leftSideColor='FF00FF00' rightSideColor='FFFF0000'/>
|
||||
</home>
|
||||
"""
|
||||
@@ -170,4 +170,27 @@ class TestArchRebar(TestArchBase.TestArchBase):
|
||||
# The Shape should be the default null/empty shape.
|
||||
self.assertIsNotNone(rebar.Shape, "Rebar object should always have a Shape attribute.")
|
||||
self.assertTrue(rebar.Shape.isNull(),
|
||||
"Rebar.Shape should be a null shape if no Base is provided.")
|
||||
"Rebar.Shape should be a null shape if no Base is provided.")
|
||||
|
||||
def test_RebarMe(self):
|
||||
"""
|
||||
Tests the creation of an Arch Rebar
|
||||
"""
|
||||
import Sketcher
|
||||
self.printTestMessage('Checking Arch Rebar...\n')
|
||||
s = Arch.makeStructure(length=2, width=3, height=5)
|
||||
sk = self.document.addObject('Sketcher::SketchObject', 'Sketch')
|
||||
sk.AttachmentSupport = (s, ["Face6"])
|
||||
sk.addGeometry(Part.LineSegment(FreeCAD.Vector(-0.85, 1.25, 0), FreeCAD.Vector(0.75, 1.25, 0)))
|
||||
sk.addGeometry(Part.LineSegment(FreeCAD.Vector(0.75, 1.25, 0), FreeCAD.Vector(0.75, -1.20, 0)))
|
||||
sk.addGeometry(Part.LineSegment(FreeCAD.Vector(0.75, -1.20, 0), FreeCAD.Vector(-0.85, -1.20, 0)))
|
||||
sk.addGeometry(Part.LineSegment(FreeCAD.Vector(-0.85, -1.20, 0), FreeCAD.Vector(-0.85, 1.25, 0)))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 0, 2, 1, 1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 1, 2, 2, 1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 2, 2, 3, 1))
|
||||
sk.addConstraint(Sketcher.Constraint('Coincident', 3, 2, 0, 1))
|
||||
self.document.recompute()
|
||||
r = Arch.makeRebar(s, sk, diameter=.1, amount=2)
|
||||
self.document.recompute()
|
||||
self.assertTrue(r, "Arch Rebar creation failed")
|
||||
self.assertFalse(r.Shape.isNull(), "Rebar shape is null")
|
||||
@@ -23,6 +23,9 @@
|
||||
# ***************************************************************************
|
||||
|
||||
import Arch
|
||||
import Draft
|
||||
import os
|
||||
import FreeCAD as App
|
||||
from bimtests import TestArchBase
|
||||
|
||||
class TestArchSectionPlane(TestArchBase.TestArchBase):
|
||||
@@ -34,4 +37,47 @@ class TestArchSectionPlane(TestArchBase.TestArchBase):
|
||||
|
||||
section_plane = Arch.makeSectionPlane(name="TestSectionPlane")
|
||||
self.assertIsNotNone(section_plane, "makeSectionPlane failed to create a section plane object.")
|
||||
self.assertEqual(section_plane.Label, "TestSectionPlane", "Section plane label is incorrect.")
|
||||
self.assertEqual(section_plane.Label, "TestSectionPlane", "Section plane label is incorrect.")
|
||||
|
||||
def testViewGeneration(self):
|
||||
"""Tests the whole TD view generation workflow"""
|
||||
|
||||
# Create a few objects
|
||||
points = [App.Vector(0.0, 0.0, 0.0), App.Vector(2000.0, 0.0, 0.0)]
|
||||
line = Draft.make_wire(points)
|
||||
wall = Arch.makeWall(line, height=2000)
|
||||
wpl = App.Placement(App.Vector(500,0,1500), App.Vector(1,0,0),-90)
|
||||
win = Arch.makeWindowPreset('Fixed', width=1000.0, height=1000.0, h1=50.0, h2=50.0, h3=50.0, w1=100.0, w2=50.0, o1=0.0, o2=50.0, placement=wpl)
|
||||
win.Hosts = [wall]
|
||||
profile = Arch.makeProfile([169, 'HEA', 'HEA100', 'H', 100.0, 96.0, 5.0, 8.0])
|
||||
column = Arch.makeStructure(profile, height=2000.0)
|
||||
column.Profile = "HEA100"
|
||||
column.Placement.Base = App.Vector(500.0, 600.0, 0.0)
|
||||
level = Arch.makeFloor()
|
||||
level.addObjects([wall, column])
|
||||
App.ActiveDocument.recompute()
|
||||
|
||||
# Create a drawing view
|
||||
section = Arch.makeSectionPlane(level)
|
||||
drawing = Arch.make2DDrawing()
|
||||
view = Draft.make_shape2dview(section)
|
||||
cut = Draft.make_shape2dview(section)
|
||||
cut.InPlace = False
|
||||
cut.ProjectionMode = "Cutfaces"
|
||||
drawing.addObjects([view, cut])
|
||||
App.ActiveDocument.recompute()
|
||||
|
||||
# Create a TD page
|
||||
tpath = os.path.join(App.getResourceDir(),"Mod","TechDraw","Templates","ISO","A3_Landscape_blank.svg")
|
||||
page = App.ActiveDocument.addObject("TechDraw::DrawPage", "Page")
|
||||
template = App.ActiveDocument.addObject("TechDraw::DrawSVGTemplate", "Template")
|
||||
template.Template = tpath
|
||||
page.Template = template
|
||||
view = App.ActiveDocument.addObject("TechDraw::DrawViewDraft", "DraftView")
|
||||
view.Source = drawing
|
||||
page.addView(view)
|
||||
view.Scale = 1.0
|
||||
view.X = "20cm"
|
||||
view.Y = "15cm"
|
||||
App.ActiveDocument.recompute()
|
||||
assert True
|
||||
34
src/Mod/BIM/bimtests/TestArchStructure.py
Normal file
34
src/Mod/BIM/bimtests/TestArchStructure.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2025 Furgo *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * FreeCAD 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD as App
|
||||
import Arch
|
||||
from bimtests import TestArchBase
|
||||
|
||||
class TestArchStructure(TestArchBase.TestArchBase):
|
||||
|
||||
def testStructure(self):
|
||||
App.Console.PrintLog ('Checking BIM Structure...\n')
|
||||
s = Arch.makeStructure(length=2,width=3,height=5)
|
||||
self.assertTrue(s,"BIM Structure failed")
|
||||
@@ -309,34 +309,39 @@ class TestArchWindow(TestArchBase.TestArchBase):
|
||||
|
||||
def test_create_window_on_xz_plane(self):
|
||||
"""Test creating a window oriented on the XZ (vertical) plane."""
|
||||
sketch = self._create_sketch_with_wires("Sketch_XZ_Plane",
|
||||
[(0,0,1000,1200), (100,100,800,1000)])
|
||||
|
||||
sketch.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(1,0,0), 90)
|
||||
# Create a a frame-like profile.
|
||||
sketch = self._create_sketch_with_wires("Sketch_XZ_Plane",
|
||||
[(0, 0, 1000, 1200), (100, 100, 800, 1000)])
|
||||
|
||||
# Orient the sketch to the XZ plane.
|
||||
sketch.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), 90)
|
||||
self.document.recompute()
|
||||
|
||||
# Create the window using explicit parts.
|
||||
window = Arch.makeWindow(baseobj=sketch, name="Window_XZ_Plane")
|
||||
window.WindowParts = [
|
||||
"Frame", "Frame", "Wire0,Wire1", "60", "0",
|
||||
"Glass", "Glass panel", "Wire1", "10", "25"
|
||||
"Frame", "Frame", "Wire0,Wire1", "60", "0", # A 60mm thick frame
|
||||
"Glass", "Glass panel", "Wire1", "10", "25" # A 10mm thick glass pane, offset by 25mm
|
||||
]
|
||||
self.document.recompute()
|
||||
|
||||
self.assertFalse(window.Shape.isNull())
|
||||
self.assertGreater(len(window.Shape.Solids), 0)
|
||||
|
||||
expected_normal_y = 1.0
|
||||
|
||||
self.assertAlmostEqual(window.Normal.x, 0.0, places=5)
|
||||
self.assertAlmostEqual(window.Normal.y, expected_normal_y, places=5,
|
||||
msg=f"Window normal Y component incorrect. Expected approx {expected_normal_y}, got {window.Normal.y}")
|
||||
self.assertAlmostEqual(window.Normal.z, 0.0, places=5)
|
||||
# Check the resulting geometry's orientation and dimensions.
|
||||
self.assertFalse(window.Shape.isNull(), "Window shape should not be null.")
|
||||
self.assertEqual(len(window.Shape.Solids), 2, "Window should contain two solids (frame and glass).")
|
||||
|
||||
bb = window.Shape.BoundBox
|
||||
|
||||
# The window's overall "thickness" is determined by the frame (60mm).
|
||||
# Its "width" (X) and "height" (Z) should be larger.
|
||||
self.assertGreater(bb.XLength, bb.YLength,
|
||||
"Window XLength (width) should be greater than YLength (thickness).")
|
||||
"Window XLength (width) should be greater than YLength (thickness).")
|
||||
self.assertGreater(bb.ZLength, bb.YLength,
|
||||
"Window ZLength (height) should be greater than YLength (thickness).")
|
||||
"Window ZLength (height) should be greater than YLength (thickness).")
|
||||
|
||||
# Verify the overall thickness is correct (60mm, from the Frame component).
|
||||
self.assertAlmostEqual(bb.YLength, 60.0, places=5,
|
||||
msg="Window thickness (YLength) is incorrect.")
|
||||
|
||||
def test_opening_property_rotates_component(self):
|
||||
"""Test that setting the Opening property rotates a hinged component."""
|
||||
@@ -559,7 +564,7 @@ class TestArchWindow(TestArchBase.TestArchBase):
|
||||
Helper to create a sketch with one or more specified rectangular wires.
|
||||
|
||||
Each rectangle is defined in the sketch's local XY plane. The sketch
|
||||
is created in the current document (`self.document`). After adding all
|
||||
is created in the current document (`self.doc`). After adding all
|
||||
geometry and basic coincident constraints for each rectangle, the
|
||||
document is recomputed.
|
||||
|
||||
@@ -608,7 +613,7 @@ class TestArchWindow(TestArchBase.TestArchBase):
|
||||
"""
|
||||
Helper to create a rectangular sketch with "Width" and "Height" named constraints.
|
||||
|
||||
The sketch is created in the current document (`self.document`) on the
|
||||
The sketch is created in the current document (`self.doc`) on the
|
||||
default XY plane. It consists of a single rectangle defined by four
|
||||
line segments, with its bottom-left corner at (0,0,0) in the
|
||||
sketch's local coordinates.
|
||||
|
||||
Reference in New Issue
Block a user