diff --git a/samples/tcl/cpu.tcl b/samples/tcl/cpu.tcl new file mode 100644 index 0000000000..4cf4d2af90 --- /dev/null +++ b/samples/tcl/cpu.tcl @@ -0,0 +1,331 @@ +# Sample model of Intel i7-4790 CPU +# Dimensions are taken from specs and foto found in Internet + +#Category: XDE +#Title: Intel i7-4790 CPU + +pload MODELING VISUALIZATION XDE + +puts "Making board..." + +# board is rectangle 37.5 x 37.5 mm with semi-round holes on two sides; +# assumed board thickness is 1 mm +dset L 37.5 +dset t 1. +polyline pboard 0 0 0 L 0 0 L L 0 0 L 0 0 0 0 +mkplane fboard pboard +circle cslot -0.2 32.2 0 1 +mkedge eslot cslot +wire wslot eslot +mkplane fslot wslot +bcut fboard fboard fslot +ttranslate fslot L+0.4 0 0 +bcut fboard fboard fslot +prism board fboard 0 0 t + +# make faces representing dard-green parts of the board sides +mkoffset dgbot fboard 1 -0.5 +mkplane dgbot dgbot_1 +tcopy dgbot dgtop +ttranslate dgtop 0 0 0.5*t +box aux 36.6 17.7 0 10 8.4 2*t +bcut dgtop dgtop aux +prism pbot dgbot 0 0 0.5*t +prism ptop dgtop 0 0 0.5*t +bfuse board board pbot +bfuse board board ptop + +# add triangular faces indicating base corner of the plate +polyline btri 0.5 0.5 0 1.5 0.5 0 0.5 1.5 0 0.5 0.5 0 +polyline ttri 0.5 0.5 t 2.5 0.5 t 0.5 2.5 t 0.5 0.5 t +thrusections stri 1 1 btri ttri +bfuse board board stri + +explode board so +renamevar board_1 board + +puts "Making case..." + +# case is made of two filleted prisms, base and top +polyline lbase 3.4 1.8 t L-3.4 1.8 t L-3.4 11.4 t L-1.8 11.4 t L-1.8 25.2 t \ + L-3.4 25.2 t L-3.4 L-3 t 3.4 L-3 t 3.4 25.2 t \ + 1.8 25.2 t 1.8 11.4 t 3.4 11.4 t 3.4 1.8 t +mkplane f lbase +explode f e +chfi2d fbase f f_1 f_2 F 1.3 f_2 f_3 F 0.7 f_3 f_4 F 0.7 f_4 f_5 F 0.7 \ + f_5 f_6 F 0.7 f_6 f_7 F 1.3 f_7 f_8 F 1.3 f_8 f_9 F 0.7 \ + f_9 f_10 F 0.7 f_10 f_11 F 0.7 f_11 f_12 F 0.7 f_12 f_1 F 1.3 + +polyline ltop 4. 3.4 t L-4 3.4 t L-4 L-4.8 t 4 L-4.8 t 4. 3.4 t +mkplane f ltop +explode f e +chfi2d ftop f f_1 f_2 F 1.6 f_2 f_3 F 1.6 f_3 f_4 F 1.6 f_4 f_1 F 1.6 + +# make case, assume height of base 1 mm and top additional 2.5 mm +prism pbase fbase 0 0 1 +prism ptop ftop 0 0 3.5 +bfuse case pbase ptop + +explode case so +renamevar case_1 case + +# write text on top of the case +# note that font is chosen by availability of Unicode symbols, +# it is different from actual font found on processor +set font "Arial Unicode MS" +#set text "i\u24c2\u00a911\nINTEL\u00ae CORE\u2122 i7-4790\nSR1QF 3.60GHZ\nMALAY\nL411B540 \u24d4" +#text2brep title $text "Arial Unicode MS" 1.7 x=10 y=24 z=4.51 +# alternative variant to work-around issue #25852 +set text "i\u20dd\u20dd11\nINTEL\u20dd CORE\u2122 i7-4790\nSR1QF 3.60GHZ\nMALAY\nL411B540 \u20dd" +text2brep title0 $text $font 1.7 x=10 y=24 z=4.51 +text2brep title1 " M C" $font 0.77 x=10 y=24.2 z=4.51 +text2brep title2 "R" $font 0.77 x=15.3 y=21.9 z=4.51 +text2brep title3 "e4" $font 0.7 x=18.6 y=15.1 z=4.51 +compound title0 title1 title2 title3 title + +puts "Adding contact pads..." + +# contact pads on top side (round); we need 42 with R=0.3 and 1 with R=0.6 +pcylinder rpad 0.27 0.1 +eval compound [lrepeat 42 rpad] cpad +set lpad [explode cpad] +for {set i 1} {$i <= 20} {incr i} { + ttranslate cpad_[expr 2*$i ] [expr 4.5 + $i * 0.7] L-0.7 t + ttranslate cpad_[expr 2*$i-1] [expr 4.85 + $i * 0.7] L-1.3 t +} +ttranslate cpad_41 L-0.7 L-0.7 t +ttranslate cpad_42 L-0.7 0.7 t +pcylinder Rpad 0.5 0.1 +ttranslate Rpad 0.9 L-0.9 t +eval compound $lpad Rpad rpads + +# contact pads at the bottom +box pad -0.45 -0.27 -0.1 0.9 0.54 0.1 +trotate pad 0 0 0 0 0 1 60 +ellipse c 0 0 -0.1 0.5 0.4 +mkedge e c +wire w e +mkplane f w +prism b f 0 0 0.1 +bcommon bpad pad b +explode bpad so +renamevar bpad_1 bpad +#donly bpad; boundings bpad + +# pattern of presence of bottom pads, on XY plane (top view) +set pattern [join { +..ooooooooooooooo...ooooooooooooooooo... +.oooooooooooooooo...ooooooooooooooooooo. +.oooooooooooooooooooooooooooooooooooooo. +.oooooooooooooooooooooooooooooooooooooo. +.oooooooooooooooooooooooooooooooooooooo. +.oooooooooooooooooooooooooooooooooooooo. +.oooooooooooooooooooooooooooooooooooooo. +.oooooooooooooooooooooooooooooooooooooo. +.ooooooooooo................ooooooooooo. +.oooooooooo.................ooooooooooo. +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +..oooooooooo................oooooooooo.. +..oooooooooo................oooooooooo.. +..oooooooooo................oooooooooo.. +..oooooooooo................oooooooooo.. +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +oooooooooooo................oooooooooooo +.ooooooooooo.................ooooooooooo +.ooooooooooo................oooooooooooo +.ooooooooooooooooooooooooooooooooooooooo +oooooooooooooooooooooooooooooooooooooooo +oooooooooooooooooooooooooooooooooooooooo +oooooooooooooooooooooooooooooooooooooooo +oooooooooooooooooooooooooooooooooooooooo +.ooooooooooooooooooooooooooooooooooooooo +..oooooooooooooooo...oooooooooooooooooo. +...ooooooooooooooo...ooooooooooooooooo.. +} ""] + +set nbpads 0 +for {set i 0} {$i < 1600} {incr i} { + if { [string index $pattern $i] == "o" } { incr nbpads } +} +eval compound [lrepeat $nbpads bpad] cpad +set lpad [explode cpad] +for {set ipad 1; set iplace 0} {$ipad <= $nbpads && $iplace < 1600} {incr ipad; incr iplace} { + while { [string index $pattern $iplace] == "." } { incr iplace } + set icol [expr $iplace % 40] + set irow [expr $iplace / 40] + ttranslate cpad_$ipad [expr 1 + 0.91 * $icol] [expr [dval L] - 1 - 0.91 * $irow] 0 +} + +# round and square contact pads on top side +# note re-use of rpad object used for bootom round pads +eval compound [lrepeat 8 rpad] crpads +set lrpad [explode crpads] +ttranslate crpads_1 25.3 8.4 -0.1 +ttranslate crpads_2 12.2 29.2 -0.1 +ttranslate crpads_3 12.5 15. -0.1 +ttranslate crpads_4 12.5 18.75 -0.1 +ttranslate crpads_5 12.5 19.5 -0.1 +ttranslate crpads_6 12.5 20.25 -0.1 +ttranslate crpads_7 12.5 21. -0.1 +ttranslate crpads_8 12.5 22.5 -0.1 +box spad_1 12.21 13.75 -0.1 0.58 0.58 0.1 +box spad_2 12.21 23.2 -0.1 0.58 0.58 0.1 + +# final compound for all bottom pads +eval compound $lpad $lrpad spad_1 spad_2 bpads + +# resistor-like packages at the bottom +box rpk1 -0.6 -0.25 -0.5 0.3 0.5 0.5 +box rpk2 -0.3 -0.25 -0.5 0.6 0.5 0.5 +box rpk3 0.3 -0.25 -0.5 0.3 0.5 0.5 +compound rpk1 rpk2 rpk3 rpk + +eval compound [lrepeat 47 rpk] crpk +set lrpk [explode crpk] +# rotate first 26 packages vertically +for {set i 1} {$i <= 26} {incr i} {trotate crpk_$i 0 0 0 0 0 1 90} +# first 9 are vertical column on the right side of the bottom view +for {set i 1} {$i <= 9} {incr i} { + ttranslate crpk_$i 13.4 [expr 9.8 + 1.6 * $i] 0 +} +# next 8 are 2x4 grid in top left corner +for {set i 1} {$i <= 4} {incr i} { + ttranslate crpk_[expr 9 + $i] 23. [expr 21.5 + 1.6 * $i] 0 + ttranslate crpk_[expr 13 + $i] 24. [expr 21.5 + 1.6 * $i] 0 +} +# others are translated individually, vertical first, bottom to top +ttranslate crpk_18 21.5 9.4 0 +ttranslate crpk_19 21.5 11.0 0 +ttranslate crpk_20 21.5 12.6 0 +ttranslate crpk_21 22.5 9.8 0 +ttranslate crpk_22 20.0 12.2 0 +ttranslate crpk_23 24.0 13.6 0 +ttranslate crpk_24 24.0 15.2 0 +ttranslate crpk_25 19.5 16.0 0 +ttranslate crpk_26 20.5 16.0 0 +# now horizontal, bottom to top +ttranslate crpk_27 23.7 9.5 0 +ttranslate crpk_28 23.7 10.5 0 +ttranslate crpk_29 22.8 11.5 0 +ttranslate crpk_30 22.8 12.5 0 +ttranslate crpk_31 22.7 14.3 0 +ttranslate crpk_32 22.7 16.0 0 +ttranslate crpk_33 22.8 17.0 0 +ttranslate crpk_34 22.8 19.1 0 +ttranslate crpk_35 22.7 20.0 0 +ttranslate crpk_36 23.0 20.9 0 +ttranslate crpk_37 23.3 21.8 0 + +ttranslate crpk_38 19.8 21.6 0 +ttranslate crpk_39 19.8 22.6 0 +ttranslate crpk_40 19.8 23.6 0 +ttranslate crpk_41 21.6 22.2 0 +ttranslate crpk_42 21.6 23.2 0 +ttranslate crpk_43 21.6 24.2 0 + +ttranslate crpk_44 18.0 24.6 0 +ttranslate crpk_45 18.0 25.6 0 +ttranslate crpk_46 18.0 26.6 0 +ttranslate crpk_47 18.0 27.6 0 + +eval compound $lrpk brpk + +# show result in plain 3d viewer +if [info exists i7_show_3dview] { + vinit Driver1/Viewer1/View1 + vclear + vsetdispmode 1 + + vlight clear + vlight add amb + vlight add directional direction 1 -1 -2 head 1 + + vdisplay case + vsetcolor case 0.7 0.7 0.7 + + vdisplay title + vsetcolor title 0.1 0.1 0.1 + + # board is mostly yellow (edges, triangle markers) + foreach f [explode board f] { vdisplay $f; vsetcolor $f 0.7 0.5 0.3 } + # top and bottom faces are light-green (outside) and dark-green (inside) + vsetcolor board_4 0 0.6 0.55 + vsetcolor board_5 0 0.6 0.55 + vsetcolor board_12 0 0.3 0.33 + vsetcolor board_15 0 0.3 0.33 + + vdisplay rpads + vsetcolor rpads 0.7 0.6 0.4 + + vdisplay bpads + vsetcolor bpads 0.7 0.6 0.4 + + vdisplay brpk + vsetcolor brpk 0.5 0.4 0.3 + + donly board case rpads brpk; fit +} + +# make XDE document +catch {Close D} +pload OCAF XDE + +NewDocument D MDTV-XCAF + +SetName D [XAddShape D board 0] "Board" +foreach f [explode board f] { XSetColor D $f 0.7 0.5 0.3 } +XSetColor D board_4 0 0.6 0.55 +XSetColor D board_5 0 0.6 0.55 +XSetColor D board_12 0 0.3 0.33 +XSetColor D board_15 0 0.3 0.33 + +SetName D [XAddShape D case 0] "Case" +XSetColor D case 0.7 0.7 0.7 + +SetName D [XAddShape D title 0] "Case title" +XSetColor D title 0.1 0.1 0.1 + +SetName D [XAddShape D rpads 1] "Top side contact pads" +SetName D [XAddShape D bpads 1] "Bottom contact pads" +SetName D [XFindShape D bpad] "Contact pad" +SetName D [XFindShape D rpad] "Round pad" +SetName D [XFindShape D Rpad] "Big round pad" +SetName D [XFindShape D spad_1] "Square pad 1" +SetName D [XFindShape D spad_2] "Square pad 2" +XSetColor D rpad 0.7 0.6 0.4 +XSetColor D Rpad 0.7 0.6 0.4 +XSetColor D bpad 0.7 0.6 0.4 +XSetColor D spad_1 0.7 0.6 0.4 +XSetColor D spad_2 0.7 0.6 0.4 + +SetName D [XAddShape D brpk 1] "Bottom packages" +SetName D [XFindShape D rpk] "Bottom package" +XSetColor D rpk1 0.7 0.7 0.7 +XSetColor D rpk2 0.5 0.4 0.3 +XSetColor D rpk3 0.7 0.7 0.7 + +XShow D +vlight clear +vlight add amb +vlight add directional direction 1 -1 -2 head 1 +vsetdispmode 1 +vfit + +# save to STEP if variable i7_save_xde is defined (specifies file name) +if [info exists i7_save_xde] { + param write.surfacecurve.mode 0 + WriteStep D $i7_save_xde +} \ No newline at end of file diff --git a/samples/tcl/dimensions.tcl b/samples/tcl/dimensions.tcl index 9de59e5fe3..f80a4b34b0 100644 --- a/samples/tcl/dimensions.tcl +++ b/samples/tcl/dimensions.tcl @@ -1,11 +1,11 @@ -#Category: Demos -#Title: Dimensions in 3d viewer - # Dimensions demo # # It shows capability of OCC to create different kinds # of dimensions (linear and angular) with 2D or 3D text. +#Category: Visualization +#Title: Dimensions in 3d viewer + set aTopLoc [locate_data_file occ/Top.brep] set aBotLoc [locate_data_file occ/Bottom.brep] set aHatch [locate_data_file images/hatch_1.png] diff --git a/samples/tcl/pencil.tcl b/samples/tcl/pencil.tcl index 9ed2c535e6..c48eb285ca 100644 --- a/samples/tcl/pencil.tcl +++ b/samples/tcl/pencil.tcl @@ -1,6 +1,6 @@ # Sample demonstrating assignment of colors to faces in XDE -#Category: Data Exchange +#Category: XDE #Title: Assignment of colors to faces pload MODELING VISUALIZATION OCAF XDE diff --git a/samples/tcl/xde.tcl b/samples/tcl/xde.tcl index 2e00651565..63f120af31 100644 --- a/samples/tcl/xde.tcl +++ b/samples/tcl/xde.tcl @@ -1,7 +1,7 @@ # Simple sample demonstrating work with assemblies in XDE, and assignment of # names and colors to components vs. instances -#Category: Application Framework +#Category: XDE #Title: Work with assemblies, colors etc. in XDE pload MODELING diff --git a/src/AIS/AIS_ColoredShape.cxx b/src/AIS/AIS_ColoredShape.cxx index fe327eca34..de89c423ac 100644 --- a/src/AIS/AIS_ColoredShape.cxx +++ b/src/AIS/AIS_ColoredShape.cxx @@ -305,7 +305,6 @@ void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& , thePrs->SetInfiniteState (Standard_True); } - const Standard_Boolean isClosed = StdPrs_ToolShadedShape::IsClosed (myshape); if (theMode == AIS_Shaded) { // compute mesh for entire shape beforehand to ensure consistency and optimizations (parallelization) @@ -320,15 +319,59 @@ void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& , StdPrs_ShadedShape::Tessellate (myshape, myDrawer); } - // 1) myShapeColors + myshape --> array[TopAbs_ShapeEnum] of map of color-to-compound - DataMapOfShapeCompd aTypeKeyshapeDrawshapeArray[(size_t )TopAbs_SHAPE]; - dispatchColors (myshape, myShapeColors, aTypeKeyshapeDrawshapeArray); + TopoDS_Compound anOpened, aClosed; + BRep_Builder aBuilder; + aBuilder.MakeCompound (aClosed); + aBuilder.MakeCompound (anOpened); + if (theMode == AIS_Shaded && myshape.ShapeType() <= TopAbs_SOLID) + { + StdPrs_ShadedShape::ExploreSolids (myshape, aBuilder, aClosed, anOpened, Standard_False); + } + else + { + aBuilder.Add (anOpened, myshape); + } - // 2) finally add appropriate presentations (1 color -- 1 compound) according to theMode + // myShapeColors + anOpened --> array[TopAbs_ShapeEnum] of map of color-to-compound + DataMapOfShapeCompd aDispatchedOpened [(size_t)TopAbs_SHAPE]; + dispatchColors (anOpened, myShapeColors, aDispatchedOpened); + addShapesWithCustomProps (thePrs, aDispatchedOpened, theMode, StdPrs_Volume_Opened); + + if (theMode == AIS_Shaded) + { + if (isShapeEntirelyVisible()) + { + // myShapeColors + aClosed --> array[TopAbs_ShapeEnum] of map of color-to-compound + DataMapOfShapeCompd aDispatchedClosed [(size_t)TopAbs_SHAPE]; + dispatchColors (aClosed, myShapeColors, aDispatchedClosed); + addShapesWithCustomProps (thePrs, aDispatchedClosed, theMode, StdPrs_Volume_Closed); + } + else + { + for (TopoDS_Iterator aSolidIter (aClosed); aSolidIter.More(); aSolidIter.Next()) + { + DataMapOfShapeCompd aDispatchedClosed [(size_t)TopAbs_SHAPE]; + dispatchColors (aSolidIter.Value(), myShapeColors, aDispatchedClosed); + addShapesWithCustomProps (thePrs, aDispatchedClosed, theMode, + isShapeEntirelyVisible (aDispatchedClosed) ? StdPrs_Volume_Closed : StdPrs_Volume_Opened); + } + } + } +} + +//======================================================================= +//function : addShapesWithCustomProps +//purpose : +//======================================================================= +void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation)& thePrs, + DataMapOfShapeCompd* theDispatched, + const Standard_Integer theMode, + const StdPrs_Volume theVolume) +{ Handle(AIS_ColoredDrawer) aCustomDrawer; for (size_t aShType = 0; aShType < (size_t )TopAbs_SHAPE; ++aShType) { - DataMapOfShapeCompd& aKeyshapeDrawshapeMap = aTypeKeyshapeDrawshapeArray[aShType]; + DataMapOfShapeCompd& aKeyshapeDrawshapeMap = theDispatched[aShType]; for (DataMapOfShapeCompd::Iterator aMapIter (aKeyshapeDrawshapeMap); aMapIter.More(); aMapIter.Next()) { @@ -351,30 +394,15 @@ void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& , // Draw each kind of subshapes and personal-colored shapes in a separate group // since it's necessary to set transparency/material for all subshapes // without affecting their unique colors - Handle(Graphic3d_Group) aCurrGroup = Prs3d_Root::NewGroup (thePrs); - switch (theMode) + if (theMode == AIS_Shaded + && aShapeDraw.ShapeType() <= TopAbs_FACE + && !IsInfinite()) { - default: - case AIS_Shaded: - { - if ((Standard_Integer )aShapeDraw.ShapeType() <= TopAbs_FACE - && !IsInfinite()) - { - StdPrs_ShadedShape::Add (thePrs, aShapeDraw, aDrawer); - - aDrawer->SetShadingAspectGlobal (Standard_False); - Handle(Graphic3d_AspectFillArea3d) anAsp = aDrawer->ShadingAspect()->Aspect(); - isClosed ? anAsp->SuppressBackFace() : anAsp->AllowBackFace(); - aCurrGroup->SetGroupPrimitivesAspect (anAsp); - break; - } - // compute wire-frame otherwise - } - case AIS_WireFrame: - { - StdPrs_WFDeflectionShape::Add (thePrs, aShapeDraw, aDrawer); - break; - } + StdPrs_ShadedShape::Add (thePrs, aShapeDraw, aDrawer, theVolume); + } + else + { + StdPrs_WFDeflectionShape::Add (thePrs, aShapeDraw, aDrawer); } } } @@ -448,22 +476,23 @@ Standard_Boolean AIS_ColoredShape::dispatchColors (const TopoDS_Shape& th } //! Function to check if specified compound is sub-shape of another one -inline Standard_Boolean isContainCompound (const TopoDS_Shape& theShape, - const TopoDS_Compound& theCompound) +inline Standard_Boolean isFirstCmpContainSecondOne (const TopoDS_Shape& theFirstCmp, + const TopoDS_Shape& theSecondCmp) { - if (theShape.ShapeType() != TopAbs_COMPOUND) + if (theFirstCmp.ShapeType() != TopAbs_COMPOUND + || theSecondCmp.ShapeType() != TopAbs_COMPOUND) { return Standard_False; } - for (TopoDS_Iterator aSubShapeIter (theShape); aSubShapeIter.More(); aSubShapeIter.Next()) + for (TopoDS_Iterator aFirstCmpIter (theFirstCmp); aFirstCmpIter.More(); aFirstCmpIter.Next()) { - if (aSubShapeIter.Value().ShapeType() != TopAbs_COMPOUND) + if (aFirstCmpIter.Value().ShapeType() != TopAbs_COMPOUND) { continue; } - else if (aSubShapeIter.Value() == theCompound - || isContainCompound (aSubShapeIter.Value(), theCompound)) + else if (aFirstCmpIter.Value() == theSecondCmp + || isFirstCmpContainSecondOne (aFirstCmpIter.Value(), theSecondCmp)) { return Standard_True; } @@ -487,43 +516,8 @@ void AIS_ColoredShape::dispatchColors (const TopoDS_Shape& theBaseShape, for (DataMapOfShapeColor::Iterator aKeyShapeIter (theKeyshapeColorMap); aKeyShapeIter.More(); aKeyShapeIter.Next()) { - const TopoDS_Shape& aKeySh = aKeyShapeIter.Key(); - const TopAbs_ShapeEnum aType = aKeySh.ShapeType(); - TopAbs_ShapeEnum aSubType = (aType == TopAbs_SOLID || aType == TopAbs_SHELL) - ? TopAbs_FACE - : (aType == TopAbs_WIRE ? TopAbs_EDGE : TopAbs_SHAPE); - switch (aSubType) - { - case TopAbs_SHAPE: - { - if (aType == TopAbs_COMPOUND - && !isContainCompound (theBaseShape, TopoDS::Compound (aKeySh))) - { - for (TopoDS_Iterator aSubShapeIter (aKeySh); aSubShapeIter.More(); aSubShapeIter.Next()) - { - if (!aSubshapeKeyshapeMap.IsBound (aSubShapeIter.Value())) - { - aSubshapeKeyshapeMap.Bind (aSubShapeIter.Value(), aKeySh); - } - } - } - else - { - aSubshapeKeyshapeMap.Bind (aKeySh, aKeySh); - } - break; - } - default: - { - for (TopExp_Explorer anExp (aKeySh, aSubType); anExp.More(); anExp.Next()) - { - if (!aSubshapeKeyshapeMap.IsBound (anExp.Current())) - { - aSubshapeKeyshapeMap.Bind (anExp.Current(), aKeySh); - } - } - } - } + const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key(); + bindSubShapes (aSubshapeKeyshapeMap, theBaseShape, aKeyShape, aKeyShape); } // Fill the array of maps per shape type @@ -531,3 +525,101 @@ void AIS_ColoredShape::dispatchColors (const TopoDS_Shape& theBaseShape, aSubshapeKeyshapeMap, TopAbs_SHAPE, theTypeKeyshapeDrawshapeArray); } + +//======================================================================= +//function : isShapeEntirelyVisible +//purpose : +//======================================================================= +Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible (DataMapOfShapeCompd* theDispatched) const +{ + Handle(AIS_ColoredDrawer) aCustomDrawer; + for (size_t aShType = (size_t )TopAbs_COMPOUND; aShType <= (size_t )TopAbs_FACE; ++aShType) + { + const DataMapOfShapeCompd& aKeyshapeDrawshapeMap = theDispatched[aShType]; + for (DataMapOfShapeCompd::Iterator aMapIter (aKeyshapeDrawshapeMap); aMapIter.More(); aMapIter.Next()) + { + if (myShapeColors.Find (aMapIter.Key(), aCustomDrawer) + && !aCustomDrawer.IsNull() + && aCustomDrawer->IsHidden()) + { + return Standard_False; + } + } + } + return Standard_True; +} + +//======================================================================= +//function : isShapeEntirelyVisible +//purpose : +//======================================================================= +Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible() const +{ + for (DataMapOfShapeColor::Iterator aMapIter (myShapeColors); aMapIter.More(); aMapIter.Next()) + { + if (aMapIter.Value()->IsHidden()) + { + return Standard_False; + } + } + return Standard_True; +} + +//======================================================================= +//function : bindSubShapes +//purpose : +//======================================================================= +void AIS_ColoredShape::bindSubShapes (DataMapOfShapeShape& theSubshapeKeyshapeMap, + const TopoDS_Shape& theBaseShape, + const TopoDS_Shape& theShapeWithColor, + const TopoDS_Shape& theColorKeyShape) +{ + TopAbs_ShapeEnum aShapeWithColorType = theShapeWithColor.ShapeType(); + if (aShapeWithColorType == TopAbs_COMPOUND) + { + if (isFirstCmpContainSecondOne (theBaseShape, theShapeWithColor)) + { + if (!theSubshapeKeyshapeMap.IsBound (theShapeWithColor)) + { + theSubshapeKeyshapeMap.Bind (theShapeWithColor, theColorKeyShape); + } + } + else + { + for (TopoDS_Iterator aSubShapeIter (theShapeWithColor); aSubShapeIter.More(); aSubShapeIter.Next()) + { + bindSubShapes (theSubshapeKeyshapeMap, theBaseShape, aSubShapeIter.Value(), theColorKeyShape); + } + } + } + else if (aShapeWithColorType == TopAbs_SOLID || aShapeWithColorType == TopAbs_SHELL) + { + for (TopExp_Explorer anExp (theShapeWithColor, TopAbs_FACE); anExp.More(); anExp.Next()) + { + if (!theSubshapeKeyshapeMap.IsBound (anExp.Current())) + { + theSubshapeKeyshapeMap.Bind (anExp.Current(), theColorKeyShape); + } + } + } + else if (aShapeWithColorType == TopAbs_WIRE) + { + for (TopExp_Explorer anExp (theShapeWithColor, TopAbs_EDGE); anExp.More(); anExp.Next()) + { + if (!theSubshapeKeyshapeMap.IsBound (anExp.Current())) + { + theSubshapeKeyshapeMap.Bind (anExp.Current(), theColorKeyShape); + } + } + } + else + { + // bind single face, edge and vertex + // force rebind if required due to the color of single shape has + // higher priority than the color of "compound" shape (wire is a + // compound of edges, shell is a compound of faces) that contains + // this single shape. + theSubshapeKeyshapeMap.Bind (theShapeWithColor, theColorKeyShape); + } +} + diff --git a/src/AIS/AIS_ColoredShape.hxx b/src/AIS/AIS_ColoredShape.hxx index c9affe1d1a..08300047fb 100644 --- a/src/AIS/AIS_ColoredShape.hxx +++ b/src/AIS/AIS_ColoredShape.hxx @@ -23,6 +23,7 @@ #include #include #include +#include //! Customizable properties. class AIS_ColoredDrawer : public AIS_Drawer @@ -137,6 +138,37 @@ protected: const DataMapOfShapeColor& theKeyshapeColorMap, DataMapOfShapeCompd* theTypeKeyshapeDrawshapeArray); +protected: + + //! Add shape to presentation + //! @param thePrs the presentation + //! @param theDispatched the shapes map with unique attributes + //! @param theMode display mode + //! @param theVolume how to interpret theDispatched shapes - as Closed volumes, as Open volumes + //! or to perform Autodetection + Standard_EXPORT void addShapesWithCustomProps (const Handle(Prs3d_Presentation)& thePrs, + DataMapOfShapeCompd* theDispatched, + const Standard_Integer theMode, + const StdPrs_Volume theVolume); + + //! Check all shapes from myShapeColorsfor visibility + Standard_EXPORT Standard_Boolean isShapeEntirelyVisible() const; + + //! Check a shape with unique attributes for visibility of all 2d subshape + Standard_EXPORT Standard_Boolean isShapeEntirelyVisible (DataMapOfShapeCompd* theDispatched) const; + + //! Resolve (parse) theKeyShape into subshapes, search in they for theBaseShape, + //! bind all resolved subshapes with theOriginKeyShape and store all binds in theSubshapeKeyshapeMap + //! @param theSubshapeKeyshapeMap shapes map: resolved and found theBaseShape subshape -> theOriginKeyShape + //! @param theBaseShape a shape to be sought + //! @param theBaseKey a shape to be resolved (parse) into smaller (in topological sense) + //! subshapes for new bind cycle + //! @param theOriginKeyShape the key to be used for undetailed shapes (default colors) + Standard_EXPORT static void bindSubShapes (DataMapOfShapeShape& theSubshapeKeyshapeMap, + const TopoDS_Shape& theBaseShape, + const TopoDS_Shape& theKeyShape, + const TopoDS_Shape& theOriginKeyShape); + protected: DataMapOfShapeColor myShapeColors; diff --git a/src/StdPrs/StdPrs.cdl b/src/StdPrs/StdPrs.cdl index a3bf056139..d3dfe3464f 100644 --- a/src/StdPrs/StdPrs.cdl +++ b/src/StdPrs/StdPrs.cdl @@ -35,6 +35,7 @@ uses TopoDS, TopExp, TopAbs, + BRep, BRepTools, Bnd, TColStd, @@ -48,6 +49,17 @@ uses Graphic3d is + + enumeration Volume is + Volume_Autodetection, + Volume_Closed, + Volume_Opened + end Volume; + ---Purpose: defines the way how to interpret input shapes + -- Volume_Autodetection to perform Autodetection (would split input shape into two groups) + -- Volume_Closed as Closed volumes (to activate back-face culling and capping plane algorithms) + -- Volume_Opened as Open volumes (shells or solids with holes) + class ToolPoint; class ToolVertex; class ToolRFace; diff --git a/src/StdPrs/StdPrs_ShadedShape.cdl b/src/StdPrs/StdPrs_ShadedShape.cdl index 385bc33256..2f722b9a44 100755 --- a/src/StdPrs/StdPrs_ShadedShape.cdl +++ b/src/StdPrs/StdPrs_ShadedShape.cdl @@ -24,7 +24,10 @@ uses Presentation from Prs3d, Drawer from Prs3d, Shape from TopoDS, - Pnt2d from gp + Pnt2d from gp, + Builder from BRep, + Compound from TopoDS, + Volume from StdPrs is @@ -32,9 +35,11 @@ is thePresentation : Presentation from Prs3d; theShape : Shape from TopoDS; theDrawer : Drawer from Prs3d; - theToExploreSolids : Boolean from Standard = Standard_True); + theVolume : Volume from StdPrs = StdPrs_Volume_Autodetection); ---Purpose: Shades . - -- @param theToExploreSolids when set to true, explodes compound into two groups - with closed Solids and open Shells + -- @param theVolumeType defines the way how to interpret input shapes - as Closed volumes (to activate back-face + -- culling and capping plane algorithms), as Open volumes (shells or solids with holes) + -- or to perform Autodetection (would split input shape into two groups) Add (myclass; thePresentation : Presentation from Prs3d; @@ -44,13 +49,24 @@ is theUVOrigin : Pnt2d from gp; theUVRepeat : Pnt2d from gp; theUVScale : Pnt2d from gp; - theToExploreSolids : Boolean from Standard = Standard_True); + theVolume : Volume from StdPrs = StdPrs_Volume_Autodetection); ---Purpose: Shades with texture coordinates. - -- @param theToExploreSolids when set to true, explodes compound into two groups - with closed Solids and open Shells + -- @param theVolumeType defines the way how to interpret input shapes - as Closed volumes (to activate back-face + -- culling and capping plane algorithms), as Open volumes (shells or solids with holes) + -- or to perform Autodetection (would split input shape into two groups) Tessellate (myclass; theShape : Shape from TopoDS; theDrawer : Drawer from Prs3d); ---Purpose: Validates triangulation within the shape and performs tessellation if necessary. + ExploreSolids (myclass; + theShape : Shape from TopoDS; + theBuilder : Builder from BRep; + theClosed : out Compound from TopoDS; + theOpened : out Compound from TopoDS; + theIgnore1DSubShape : Boolean from Standard); + ---Purpose: Searches closed and unclosed subshapes in shape structure and puts them + -- into two compounds for separate processing of closed and unclosed sub-shapes + end ShadedShape; diff --git a/src/StdPrs/StdPrs_ShadedShape.cxx b/src/StdPrs/StdPrs_ShadedShape.cxx index 160417bd5a..d6e8403257 100644 --- a/src/StdPrs/StdPrs_ShadedShape.cxx +++ b/src/StdPrs/StdPrs_ShadedShape.cxx @@ -237,56 +237,6 @@ namespace return anArray; } - //! Searches closed and unclosed subshapes in shape structure - //! and puts them into two compounds for separate processing of closed and unclosed sub-shapes. - static void exploreSolids (const TopoDS_Shape& theShape, - const BRep_Builder& theBuilder, - TopoDS_Compound& theCompoundForClosed, - TopoDS_Compound& theCompoundForOpened) - { - if (theShape.IsNull()) - { - return; - } - - switch (theShape.ShapeType()) - { - case TopAbs_COMPOUND: - case TopAbs_COMPSOLID: - { - for (TopoDS_Iterator anIter (theShape); anIter.More(); anIter.Next()) - { - exploreSolids (anIter.Value(), theBuilder, theCompoundForClosed, theCompoundForOpened); - } - return; - } - case TopAbs_SOLID: - { - for (TopoDS_Iterator anIter (theShape); anIter.More(); anIter.Next()) - { - const TopoDS_Shape& aSubShape = anIter.Value(); - const Standard_Boolean isClosed = aSubShape.ShapeType() == TopAbs_SHELL && - BRep_Tool::IsClosed (aSubShape) && - StdPrs_ToolShadedShape::IsTriangulated (aSubShape); - theBuilder.Add (isClosed ? theCompoundForClosed : theCompoundForOpened, aSubShape); - } - return; - } - case TopAbs_SHELL: - case TopAbs_FACE: - { - theBuilder.Add (theCompoundForOpened, theShape); - return; - } - case TopAbs_WIRE: - case TopAbs_EDGE: - case TopAbs_VERTEX: - case TopAbs_SHAPE: - default: - return; - } - } - //! Prepare shaded presentation for specified shape static Standard_Boolean shadeFromShape (const TopoDS_Shape& theShape, const Handle(Prs3d_Presentation)& thePrs, @@ -435,6 +385,66 @@ namespace } }; +// ======================================================================= +// function : ExploreSolids +// purpose : +// ======================================================================= +void StdPrs_ShadedShape::ExploreSolids (const TopoDS_Shape& theShape, + const BRep_Builder& theBuilder, + TopoDS_Compound& theClosed, + TopoDS_Compound& theOpened, + const Standard_Boolean theIgnore1DSubShape) +{ + if (theShape.IsNull()) + { + return; + } + + switch (theShape.ShapeType()) + { + case TopAbs_COMPOUND: + case TopAbs_COMPSOLID: + { + for (TopoDS_Iterator anIter (theShape); anIter.More(); anIter.Next()) + { + ExploreSolids (anIter.Value(), theBuilder, theClosed, theOpened, theIgnore1DSubShape); + } + return; + } + case TopAbs_SOLID: + { + for (TopoDS_Iterator anIter (theShape); anIter.More(); anIter.Next()) + { + const TopoDS_Shape& aSubShape = anIter.Value(); + const Standard_Boolean isClosed = aSubShape.ShapeType() == TopAbs_SHELL && + BRep_Tool::IsClosed (aSubShape) && + StdPrs_ToolShadedShape::IsTriangulated (aSubShape); + theBuilder.Add (isClosed ? theClosed : theOpened, aSubShape); + } + return; + } + case TopAbs_SHELL: + case TopAbs_FACE: + { + theBuilder.Add (theOpened, theShape); + return; + } + case TopAbs_WIRE: + case TopAbs_EDGE: + case TopAbs_VERTEX: + { + if (!theIgnore1DSubShape) + { + theBuilder.Add (theOpened, theShape); + } + return; + } + case TopAbs_SHAPE: + default: + return; + } +} + // ======================================================================= // function : Add // purpose : @@ -442,11 +452,11 @@ namespace void StdPrs_ShadedShape::Add (const Handle(Prs3d_Presentation)& thePrs, const TopoDS_Shape& theShape, const Handle(Prs3d_Drawer)& theDrawer, - const Standard_Boolean theToExploreSolids) + const StdPrs_Volume theVolume) { gp_Pnt2d aDummy; StdPrs_ShadedShape::Add (thePrs, theShape, theDrawer, - Standard_False, aDummy, aDummy, aDummy, theToExploreSolids); + Standard_False, aDummy, aDummy, aDummy, theVolume); } // ======================================================================= @@ -484,7 +494,7 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs, const gp_Pnt2d& theUVOrigin, const gp_Pnt2d& theUVRepeat, const gp_Pnt2d& theUVScale, - const Standard_Boolean theToExploreSolids) + const StdPrs_Volume theVolume) { if (theShape.IsNull()) { @@ -503,14 +513,14 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs, if ((theShape.ShapeType() == TopAbs_COMPOUND || theShape.ShapeType() == TopAbs_COMPSOLID || theShape.ShapeType() == TopAbs_SOLID) - && theToExploreSolids) + && theVolume == StdPrs_Volume_Autodetection) { // collect two compounds: for opened and closed (solid) sub-shapes TopoDS_Compound anOpened, aClosed; BRep_Builder aBuilder; aBuilder.MakeCompound (aClosed); aBuilder.MakeCompound (anOpened); - exploreSolids (theShape, aBuilder, aClosed, anOpened); + ExploreSolids (theShape, aBuilder, aClosed, anOpened, Standard_True); TopoDS_Iterator aShapeIter (aClosed); if (aShapeIter.More()) @@ -528,9 +538,10 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs, } else { + // if the shape type is not compound, composolid or solid, use autodetection back-facing filled shadeFromShape (theShape, thePrs, theDrawer, theHasTexels, theUVOrigin, theUVRepeat, theUVScale, - StdPrs_ToolShadedShape::IsClosed (theShape)); + (theVolume == StdPrs_Volume_Closed ? Standard_True : Standard_False)); } if (theDrawer->IsFaceBoundaryDraw()) diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index 2b3a5ceb4b..7790ba10e0 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -1377,6 +1377,9 @@ static int VSetInteriorStyle (Draw_Interpretor& theDI, //! Auxiliary structure for VAspects struct ViewerTest_AspectsChangeSet { + Standard_Integer ToSetVisibility; + Standard_Integer Visibility; + Standard_Integer ToSetColor; Quantity_Color Color; @@ -1394,7 +1397,9 @@ struct ViewerTest_AspectsChangeSet //! Empty constructor ViewerTest_AspectsChangeSet() - : ToSetColor (0), + : ToSetVisibility (0), + Visibility (1), + ToSetColor (0), Color (DEFAULT_COLOR), ToSetLineWidth (0), LineWidth (1.0), @@ -1406,7 +1411,8 @@ struct ViewerTest_AspectsChangeSet //! @return true if no changes have been requested Standard_Boolean IsEmpty() const { - return ToSetLineWidth == 0 + return ToSetVisibility == 0 + && ToSetLineWidth == 0 && ToSetTransparency == 0 && ToSetColor == 0 && ToSetMaterial == 0; @@ -1416,6 +1422,11 @@ struct ViewerTest_AspectsChangeSet Standard_Boolean Validate (const Standard_Boolean theIsSubPart) const { Standard_Boolean isOk = Standard_True; + if (Visibility != 0 && Visibility != 1) + { + std::cout << "Error: the visibility should be equal to 0 or 1 (0 - invisible; 1 - visible) (specified " << Visibility << ")\n"; + isOk = Standard_False; + } if (LineWidth <= 0.0 || LineWidth > 10.0) { @@ -1640,6 +1651,18 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, aChangeSet->Transparency = 0.0; } } + else if (anArg == "-setvis" + || anArg == "-setvisibility") + { + if (++anArgIter >= theArgNb) + { + std::cout << "Error: wrong syntax at " << anArg << "\n"; + return 1; + } + + aChangeSet->ToSetVisibility = 1; + aChangeSet->Visibility = Draw::Atoi (theArgVec[anArgIter]); + } else if (anArg == "-setalpha") { if (++anArgIter >= theArgNb) @@ -1782,6 +1805,8 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, } else if (anArg == "-unset") { + aChangeSet->ToSetVisibility = 1; + aChangeSet->Visibility = 1; aChangeSet->ToSetLineWidth = -1; aChangeSet->LineWidth = 1.0; aChangeSet->ToSetTransparency = -1; @@ -1819,7 +1844,7 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, Handle(AIS_InteractiveObject) aPrs = aPrsIter.Current(); Handle(AIS_ColoredShape) aColoredPrs; Standard_Boolean toDisplay = Standard_False; - if (aChanges.Length() > 1) + if (aChanges.Length() > 1 || aChangeSet->ToSetVisibility == 1) { Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs); if (aShapePrs.IsNull()) @@ -1844,7 +1869,12 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, { NCollection_Sequence::Iterator aChangesIter (aChanges); aChangeSet = &aChangesIter.ChangeValue(); - if (aChangeSet->ToSetMaterial == 1) + if (aChangeSet->ToSetVisibility == 1) + { + Handle(AIS_ColoredDrawer) aColDrawer = aColoredPrs->CustomAspects (aColoredPrs->Shape()); + aColDrawer->SetHidden (aChangeSet->Visibility == 0); + } + else if (aChangeSet->ToSetMaterial == 1) { aCtx->SetMaterial (aPrs, aChangeSet->Material, Standard_False); } @@ -1884,6 +1914,11 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, aSubShapeIter.More(); aSubShapeIter.Next()) { const TopoDS_Shape& aSubShape = aSubShapeIter.Value(); + if (aChangeSet->ToSetVisibility == 1) + { + Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape); + aCurColDrawer->SetHidden (aChangeSet->Visibility == 0); + } if (aChangeSet->ToSetColor == 1) { aColoredPrs->SetCustomColor (aSubShape, aChangeSet->Color); @@ -4625,6 +4660,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands) theCommands.Add("vaspects", "vaspects [-noupdate|-update] [name1 [name2 [...]]]" + "\n\t\t: [-setvisibility 0|1]" "\n\t\t: [-setcolor ColorName] [-setcolor R G B] [-unsetcolor]" "\n\t\t: [-setmaterial MatName] [-unsetmaterial]" "\n\t\t: [-settransparency Transp] [-unsettransparency]" diff --git a/tests/bugs/vis/bug25687_1 b/tests/bugs/vis/bug25687_1 new file mode 100644 index 0000000000..499d50a6d9 --- /dev/null +++ b/tests/bugs/vis/bug25687_1 @@ -0,0 +1,28 @@ +puts "============" +puts "OCC25687" +puts "AIS_ColoredShape should activate back-face culling for valid Solids." +puts "============" +puts "" + +set x_check_coord 225 +set y_check_coord 32 + +box b 10 10 10 +explode b f + +vinit View1 +vclear +vaxo +vsetdispmode 1 + +vdisplay b +vviewparams -proj 0.5 0.3 0.1 +vfit + +vaspects b -subshapes b_1 -setcolor GREEN + +if {"[vreadpixel ${x_check_coord} ${y_check_coord} rgb name]" == "GREEN"} { + puts "Error: back-face culling should be turned ON, but back-face is still visible." +} + +set only_screen 1 diff --git a/tests/bugs/vis/bug25687_2 b/tests/bugs/vis/bug25687_2 new file mode 100644 index 0000000000..48c1939e4a --- /dev/null +++ b/tests/bugs/vis/bug25687_2 @@ -0,0 +1,29 @@ +puts "============" +puts "OCC25687" +puts "AIS_ColoredShape should disable back-face culling for Solids with hidden Face" +puts "============" +puts "" + +set x_check_coord 200 +set y_check_coord 200 + +box b 10 10 10 +explode b f + +vinit View1 +vclear +vaxo +vsetdispmode 1 + +vdisplay b +vviewparams -proj 0.5 0.3 0.1 +vfit + +vaspects b -subshapes b_1 -setcolor GREEN +vaspects b -subshapes b_2 -setvis 0 + +if {"[vreadpixel ${x_check_coord} ${y_check_coord} rgb name]" != "GREEN"} { + puts "Error: back-face culling should be disabled, but seems to be not." +} + +set only_screen 1