]> OCCT Git - occt-copy.git/commitdiff
0025687: Visualization, XCAF - eliminate visual artifacts at the edges of faces
authoribs <ibs@opencascade.com>
Thu, 26 Feb 2015 09:50:32 +0000 (12:50 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 26 Feb 2015 09:51:24 +0000 (12:51 +0300)
AIS_ColoredShape::Compute() - improve logic to split input shape into Closed and Open volumes
with back-face culling enabled when possible.

Change last argument of method StdPrs_ShadedShape::Add() from boolean to enumeration StdPrs_Volume
which controls parsing of Closed/Open volumes within input shape.
Make method StdPrs_ShadedShape::ExploreSolids() public.

Extend Draw Harness command vaspects with option -setvisibility to hide subshape (using AIS_ColoredShape).
Add new test cases bugs/bis/bug25687_1 and bugs/bis/bug25687_2.

the logic of bindSubShapes method clarified

Conflicts:

src/AIS/AIS_ColoredShape.cxx

AIS_ColoredShape::dispatchColors considers the colors of displayed shapes in connection with specific priority

the color of specific shape can be exported from several ways: the color of this shape, the color of a compound containing this shape. The highest priority has the color of shape than the one of the compound. The color with highest priority will be displayed.

This patch accounts for the highest priority of the shape color.

For example: w - wire has GREEN color; e - edge has RED color; "w" contains "e"; all edges of "w" will be displayed in GREEN color except "e" edge, it will be displayed in RED color

Added sample generating model of Intel i7-4790 CPU on which the problem can be reproduced

12 files changed:
samples/tcl/cpu.tcl [new file with mode: 0644]
samples/tcl/dimensions.tcl
samples/tcl/pencil.tcl
samples/tcl/xde.tcl
src/AIS/AIS_ColoredShape.cxx
src/AIS/AIS_ColoredShape.hxx
src/StdPrs/StdPrs.cdl
src/StdPrs/StdPrs_ShadedShape.cdl
src/StdPrs/StdPrs_ShadedShape.cxx
src/ViewerTest/ViewerTest.cxx
tests/bugs/vis/bug25687_1 [new file with mode: 0644]
tests/bugs/vis/bug25687_2 [new file with mode: 0644]

diff --git a/samples/tcl/cpu.tcl b/samples/tcl/cpu.tcl
new file mode 100644 (file)
index 0000000..4cf4d2a
--- /dev/null
@@ -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
index 9de59e5fe3f1442c197e5db8df6b3bf846d11d27..f80a4b34b0f07233bc1694523705fdcc26c2856e 100644 (file)
@@ -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]
index 9ed2c535e6b21b966ca15cc35e60eb05b9b7f437..c48eb285ca29e336a5e44bd86e135c8439b0987b 100644 (file)
@@ -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
index 2e00651565ee42b9b4ab9b2875da4be3733867b6..63f120af312e88e9dcbe346dfb0ba3c1e8af1788 100644 (file)
@@ -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
index fe327eca345fa7c6ed5dc6bab8bb4e3269e0343f..de89c423ac77763b7901f43e54b4fe1c15cf7a8d 100644 (file)
@@ -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);
+  }
+
+  // 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);
+      }
+    }
+  }
+}
 
-  // 2) finally add appropriate presentations (1 color -- 1 compound) according to theMode
+//=======================================================================
+//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,47 +516,110 @@ 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)
+    const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
+    bindSubShapes (aSubshapeKeyshapeMap, theBaseShape, aKeyShape, aKeyShape);
+  }
+
+  // Fill the array of maps per shape type
+  dispatchColors (theBaseShape, 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())
     {
-      case TopAbs_SHAPE:
+      if (myShapeColors.Find (aMapIter.Key(), aCustomDrawer)
+      && !aCustomDrawer.IsNull()
+      &&  aCustomDrawer->IsHidden())
       {
-        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;
+        return Standard_False;
       }
-      default:
+    }
+  }
+  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))
       {
-        for (TopExp_Explorer anExp (aKeySh, aSubType); anExp.More(); anExp.Next())
-        {
-          if (!aSubshapeKeyshapeMap.IsBound (anExp.Current()))
-          {
-            aSubshapeKeyshapeMap.Bind (anExp.Current(), aKeySh);
-          }
-        }
+        theSubshapeKeyshapeMap.Bind (theShapeWithColor, theColorKeyShape);
+      }
+    }
+    else
+    {
+      for (TopoDS_Iterator aSubShapeIter (theShapeWithColor); aSubShapeIter.More(); aSubShapeIter.Next())
+      {
+        bindSubShapes (theSubshapeKeyshapeMap, theBaseShape, aSubShapeIter.Value(), theColorKeyShape);
       }
     }
   }
-
-  // Fill the array of maps per shape type
-  dispatchColors (theBaseShape, theBaseShape,
-                  aSubshapeKeyshapeMap, TopAbs_SHAPE,
-                  theTypeKeyshapeDrawshapeArray);
+  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);
+  }
 }
+
index c9affe1d1a58f38e201c475c0cc75278a34d2ff4..08300047fbc3b1be003e803fc7ff8c27964c2794 100644 (file)
@@ -23,6 +23,7 @@
 #include <NCollection_IndexedDataMap.hxx>
 #include <TopTools_ShapeMapHasher.hxx>
 #include <TopoDS_Compound.hxx>
+#include <StdPrs_Volume.hxx>
 
 //! 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;
index a3bf056139d7aad9a8021ec52f4179823022145d..d3dfe3464f6535ff8c0902920c03d0c410c7a36a 100644 (file)
@@ -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;
index 385bc3325658fcfaaa264e0e501930f93947e297..2f722b9a44ead15b96cc9a8659920c5220fbf39e 100755 (executable)
@@ -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 <theShape>.
-  -- @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 <theShape> 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;
index 160417bd5a8ba3885d9a3e77689c4f9450d235d5..d6e8403257b2e55b2f010b1d1472325a01043331 100644 (file)
@@ -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())
index 2b3a5ceb4b066f54ee7b77e3dab79783526d4232..7790ba10e0c96503c9e1b1eb00169518afb5fa1e 100644 (file)
@@ -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<ViewerTest_AspectsChangeSet>::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 (file)
index 0000000..499d50a
--- /dev/null
@@ -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 (file)
index 0000000..48c1939
--- /dev/null
@@ -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