Exemplo n.º 1
0
/*!*/
laydata::tdtdata* laydata::quadTree::merge_selected(tdtdata*& shapeRef) {
   laydata::tdtdata* mergeres = NULL;
   DBbox overlapRef = shapeRef->overlap();
   // check the entire holder for clipping...
   if (overlapRef.cliparea(_overlap) == 0) return NULL;
   // now start traversing the shapes in the current horlder one by one
   tdtdata* wdt = _first;
   while(wdt) {
      // for fully selected shapes if they overlap with the reference
      // and this is not the same shape as the reference
      if ((wdt != shapeRef) && 
          ((sh_selected == wdt->status()) || (sh_merged == wdt->status())) && 
          (overlapRef.cliparea(wdt->overlap()) != 0)) {
         // go and merge it
         mergeres = polymerge(wdt->shape2poly(), shapeRef->shape2poly());
         if (NULL != mergeres) {
            // If the merge produce a result - return the result and
            // substitute the shapeRef with its merged counterpart
            shapeRef = wdt;
            return mergeres;
         }
      }
      wdt = wdt->next();
   }
   // if we've got to this point - means that no more shapes to merge
   // in this area
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) {
         mergeres = _quads[i]->merge_selected(shapeRef);
         if (NULL != mergeres) return mergeres;
      }
   //at this point there is nothing more to traverse, so return NULL
   return NULL;
}
Exemplo n.º 2
0
/*! Checks whether a single layout object shape will fit into one of the 
childrens quadTree. It calls add() and returns success if the new layout object 
fits entirely into one of the possible subtrees or if it blows up its 
overlaping area not more than 10%. Returns false if the shape does not fit
anywhere - means it should be placed higher into the quadTree structure.\n
The method might be called recursively via the add() method.
*/
bool laydata::quadTree::fitintree(tdtdata* shape) {
   DBbox shovl = shape->overlap();
   float clipedarea[4];
   // check the clipping to see in witch region to place the shape
   for (byte i = 0; i < 4 ; i++) {
      DBbox subbox = _overlap.getcorner(i);
      clipedarea[i] = subbox.cliparea(shovl,true);
      if (-1 == clipedarea[i]) {//entirely inside the area
         if (!_quads[i]) _quads[i] = DEBUG_NEW quadTree();
         _quads[i]->add(shape);
         return true;
      }
   }
   // if we got to this point - means that the shape does not fit
   // entirely inside neither of the four sub-areas. 
   // It is a decision time then
   byte candidate = biggest(clipedarea);
   // now calculate the eventual new overlaping box
   DBbox newovl = _overlap.getcorner(candidate);
   newovl.overlap(shovl);
   // if the max area of the candidate does not blow more than 10% - 
   // then seems to be OK to get it
   if (newovl.area() < 1.1 * (_overlap.area() / 4)) {
      if (!_quads[candidate]) _quads[candidate] = DEBUG_NEW quadTree();
      _quads[candidate]->add(shape);
      return true;
   }
   return false; // shape can not be fit into any subtree
}
Exemplo n.º 3
0
/*!Cut with polygon is pretty expensive operation and despite the fact that it
is executed over selected shapes only, there is no guarantee that the user will 
not do select_all() and then polycut(), and of course nobody can trust the user.
So this method is trying to minimize the calculations by executing cutpoly only 
on the shapes that overlap somehow with the cutting polygon */
void laydata::quadTree::cutpoly_selected(pointlist& plst, DBbox& cut_overlap, 
                                                           shapeList** decure) {
   // check the entire holder for clipping...
   if (cut_overlap.cliparea(_overlap) == 0) return;
   // now start traversing the shapes in the current horlder one by one
   tdtdata* wdt = _first;
   while(wdt) {
      // for fully selected shpes if they overlap with the cutting polygon
      if ((sh_selected == wdt->status()) && 
                                    (cut_overlap.cliparea(wdt->overlap()) != 0))
         // go and clip it
         wdt->polycut(plst, decure);
      wdt = wdt->next();
   }
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->cutpoly_selected(plst, cut_overlap, decure);

}
Exemplo n.º 4
0
/*! A temporary Draw (during move/copy operations) of the container contents
 on the screen using the virtual quadTree::tmp_draw() method of the 
 parent object. */
void laydata::tdtlayer::motion_draw(const layprop::DrawProperties& drawprop,
                                                 ctmqueue& transtack) const {
   // check the entire layer for clipping...
   DBbox clip = drawprop.clipRegion();
   if (empty()) return;
   DBbox areal = overlap().overlap(transtack.front());
   if      ( clip.cliparea(areal) == 0       ) return;
   else if (!areal.visible(drawprop.ScrCTM())) return;
   quadTree::motion_draw(drawprop, transtack);
}
Exemplo n.º 5
0
short laydata::quadTree::clip_type(tenderer::TopRend& rend) const
{
   if (empty()) return 0;
   // check the entire holder for clipping...
   DBbox clip = rend.clipRegion();
   DBbox areal = _overlap.overlap(rend.topCTM());
   float clip_area = clip.cliparea(areal);
   if ( ( 0.0 == clip_area ) || (!areal.visible(rend.ScrCTM())) ) return 0;
   if (0.0 < clip_area) return 1;
   else return -1;
}
Exemplo n.º 6
0
/*! Perform the data selection using select_in box. Called by the corresponding
select methods of the parent structures in the data base - tdtlayer and tdtcell
*/
void laydata::quadTree::select_inBox(DBbox& select_in, dataList* selist, 
                                                          bool pselect) {
   // check the entire holder for clipping...
   if (select_in.cliparea(_overlap) == 0) return;
   // now start selecting one by one
   tdtdata* wdt = _first;
   while(wdt) {
      wdt->select_inBox(select_in, selist, pselect);
      wdt = wdt->next();
   }   
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->select_inBox(select_in, selist, pselect);
}
Exemplo n.º 7
0
/*! A temporary Draw (during move/copy operations) of the container contents
 on the screen using the virtual quadTree::tmp_draw() method of the 
 parent object. */
void laydata::tdtlayer::tmp_draw(const layprop::DrawProperties& drawprop,
                                                 ctmqueue& transtack) const {
   // check the entire layer for clipping...
   DBbox clip = drawprop.clipRegion();
   if (empty()) return;
   DBbox areal = overlap() * transtack.front();
   areal.normalize();
   if (clip.cliparea(areal) == 0) return;
   else {
      areal = areal * drawprop.ScrCTM();
      if (areal.area() < MIN_VISUAL_AREA) return;
   }   
   quadTree::tmp_draw(drawprop, transtack);
}
Exemplo n.º 8
0
bool laydata::DrawIterator<DataT>::secureNonEmptyDown()
{
   assert(_drawprop);
   DBbox clip = _drawprop->clipRegion();
   DBbox areal = Iterator<DataT>::_cQuad->_overlap.overlap(_ctm);
   if      (0ll == clip.cliparea(areal)      ) return false;
   else if (!areal.visible(_drawprop->scrCtm(), _drawprop->visualLimit())) return false;
   while (0 == Iterator<DataT>::_cQuad->_props._numObjects)
   {
      return this->nextSubQuad(0,Iterator<DataT>::_cQuad->_props.numSubQuads());
   }
   Iterator<DataT>::_cData = 0;
   return true;
}
Exemplo n.º 9
0
/*! Temporary draw of the container contents on the screen using the virtual 
tmp_draw methods of the tdtddata objects. This happens only if 
the current quadTree object is visible. Current clip region data is
obtained from LayoutCanvas. In a sence this method is the same as openGL_draw
without fill and not handling selected shapes*/
void laydata::quadTree::motion_draw(const layprop::DrawProperties& drawprop,
                                                   ctmqueue& transtack) const {
   if (empty()) return;
   // check the entire holder for clipping...
   DBbox clip = drawprop.clipRegion();
   DBbox areal = _overlap.overlap(transtack.front());
   if      (clip.cliparea(areal) == 0        ) return;
   else if (!areal.visible(drawprop.ScrCTM())) return;
   tdtdata* wdt = _first;
   while(wdt) {
      wdt->motion_draw(drawprop, transtack, NULL);
      wdt = wdt->next();
   }
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->motion_draw(drawprop, transtack);
}
Exemplo n.º 10
0
/*! Unselects already selected data using unselect_in box. Called by the corresponding
unselect methods of the parent structures in the data base - tdtlayer and tdtcell
*/
void laydata::quadTree::unselect_inBox(DBbox& unselect_in, dataList* unselist, 
                                                                 bool pselect) {
   // check the entire holder for clipping...
   if (unselect_in.cliparea(_overlap) == 0) return;
   tdtdata* wdt = _first;
   while (wdt) {
      // now start unselecting from the list
      dataList::iterator DI = unselist->begin();
      while ( DI != unselist->end() )
         if ((wdt == DI->first) &&
             (DI->first->unselect(unselect_in, *DI, pselect)))
               DI = unselist->erase(DI);
         else DI++;
      wdt = wdt->next();
   }   
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->unselect_inBox(unselect_in, unselist, pselect);
}
Exemplo n.º 11
0
/*! Temporary draw of the container contents on the screen using the virtual 
tmp_draw methods of the tdtddata objects. This happens only if 
the current quadTree object is visible. Current clip region data is
obtained from LayoutCanvas. In a sence this method is the same as openGL_draw
without fill and not handling selected shapes*/
void laydata::quadTree::tmp_draw(const layprop::DrawProperties& drawprop,
                                                   ctmqueue& transtack) const {
   if (empty()) return;
   // check the entire holder for clipping...
   DBbox clip = drawprop.clipRegion();   
   DBbox areal = _overlap * transtack.front(); 
   areal.normalize();
   if (clip.cliparea(areal) == 0) return;
   else {
      areal = areal * drawprop.ScrCTM();
      if (areal.area() < MIN_VISUAL_AREA) return;
   }   
   tdtdata* wdt = _first;
   while(wdt) {
      wdt->tmp_draw(drawprop, transtack);
      wdt = wdt->next();
   }
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->tmp_draw(drawprop, transtack);
}
Exemplo n.º 12
0
/*! Draw the contents of the container on the screen using the virtual 
openGL_draw methods of the tdtddata objects. This happens only if 
the current quadTree object is visible. Current clip region data is
obtained from LayoutCanvas. Draws also the select marks in case shape is
selected. \n This is the cherry of the quadTree algorithm cake*/
void laydata::quadTree::openGL_draw(ctmstack& transtack, const layprop::DrawProperties& drawprop,
                                                   const dataList* slst) const {
   if (empty()) return;
   // check the entire holder for clipping...
   DBbox clip = drawprop.clipRegion();
   DBbox areal = _overlap * transtack.top(); 
   areal.normalize();
   if (clip.cliparea(areal) == 0) return;
   else {
      areal = areal * drawprop.ScrCTM();
      if (areal.area() < MIN_VISUAL_AREA) return;
//      std::cout << "  ... with area " << areal.area() << "\n";
   }
   tdtdata* wdt = _first;
   // The drawing will be faster like this for the cells without selected shapes
   // that will be the wast majority of the cases. A bit bigger code though.
   // Seems the bargain is worth it.
   if (slst)
      while(wdt) {
         wdt->openGL_draw(transtack,drawprop);
         // in case the shape is somehow selected...
         if       (sh_selected == wdt->status()) wdt->draw_select(transtack.top());
         else if  (sh_partsel == wdt->status()) {
            dataList::const_iterator SI;
            for (SI = slst->begin(); SI != slst->end(); SI++)
               if (SI->first == wdt) break;
            assert(SI != slst->end());
            wdt->draw_select(transtack.top(), SI->second);
         }   
         wdt = wdt->next();
      }
   else
      // if there are no selected shapes
      while(wdt) {
         wdt->openGL_draw(transtack,drawprop);
         wdt = wdt->next();
      }
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->openGL_draw(transtack, drawprop, slst);
}
Exemplo n.º 13
0
/*! Draw the contents of the container on the screen using the virtual 
openGL_draw methods of the tdtddata objects. This happens only if 
the current quadTree object is visible. Current clip region data is
obtained from LayoutCanvas. Draws also the select marks in case shape is
selected. \n This is the cherry of the quadTree algorithm cake*/
void laydata::quadTree::openGL_draw(layprop::DrawProperties& drawprop,
                                                   const dataList* slst, bool fill, bool bound) const {
   if (empty()) return;
   // check the entire holder for clipping...
   DBbox clip = drawprop.clipRegion();
   DBbox areal = _overlap * drawprop.topCTM(); 
   areal.normalize();
   if (clip.cliparea(areal) == 0) return;
   else {
      areal = areal * drawprop.ScrCTM();
      if (areal.area() < MIN_VISUAL_AREA) return;
//      std::cout << "  ... with area " << areal.area() << "\n";
   }
   tdtdata* wdt = _first;
//   bool fill = drawprop.getCurrentFill();
   // The drawing will be faster like this for the cells without selected shapes
   // that will be the wast majority of the cases. A bit bigger code though.
   // Seems the bargain is worth it.
   if (slst)
   {
      while(wdt)
      {
         pointlist points;
         // precalculate drawing data
         wdt->openGL_precalc(drawprop, points);
         if (0 != points.size())
         {
            // draw the shape fill (contents of refs, arefs and texts)
            if (fill)  wdt->openGL_drawfill(drawprop, points);
            // draw the outline of the shapes and overlapping boxes 
            if (bound) wdt->openGL_drawline(drawprop, points);
            if ((sh_selected == wdt->status()) || (sh_partsel == wdt->status()))
            {
               drawprop.setLineProps(true);
               if       (sh_selected == wdt->status())
                  wdt->openGL_drawsel(points, NULL);
               else if  (sh_partsel  == wdt->status())
               {
                  dataList::const_iterator SI;
                  for (SI = slst->begin(); SI != slst->end(); SI++)
                     if (SI->first == wdt) break;
                  assert(SI != slst->end());
                  wdt->openGL_drawsel(points, SI->second);
               }
               drawprop.setLineProps(false);
            }
            wdt->openGL_postclean(drawprop, points);
         }
         wdt = wdt->next();
      }
   }
   else
   {
      // if there are no selected shapes
      while(wdt)
      {
         pointlist points;
         // precalculate drawing data
         wdt->openGL_precalc(drawprop, points);
         // draw the shape fill (contents of refs, arefs and texts)
         if (fill)  wdt->openGL_drawfill(drawprop, points);
         // draw the outline of the shapes and overlapping boxes
         if (bound) wdt->openGL_drawline(drawprop, points);
         // clean-up
         wdt->openGL_postclean(drawprop, points);
         wdt = wdt->next();
      }
   }
   
/*   // The drawing will be faster like this for the cells without selected shapes
   // that will be the wast majority of the cases. A bit bigger code though.
   // Seems the bargain is worth it.
   if (slst)
      while(wdt) {
         wdt->openGL_draw(drawprop);
         // in case the shape is somehow selected...
         if       (sh_selected == wdt->status()) wdt->draw_select(drawprop.topCTM());
         else if  (sh_partsel == wdt->status()) {
            dataList::const_iterator SI;
            for (SI = slst->begin(); SI != slst->end(); SI++)
               if (SI->first == wdt) break;
            assert(SI != slst->end());
            wdt->draw_select(drawprop.topCTM(), SI->second);
         }   
         wdt = wdt->next();
      }
   else
      // if there are no selected shapes
      while(wdt) {
         wdt->openGL_draw(drawprop);
         wdt = wdt->next();
      }*/
   for(byte i = 0; i < 4; i++) 
      if (_quads[i]) _quads[i]->openGL_draw(drawprop, slst, fill, bound);
}