int TreeListModel::rowCount(const QModelIndex &parent) const { TreeList *parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast<TreeList*>(parent.internalPointer()); return parentItem->childCount(); }
QModelIndex TreeListModel::index(int row, int column, const QModelIndex &parent) const { TreeList *parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast<TreeList*>(parent.internalPointer()); TreeList *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); else return QModelIndex(); }
QModelIndex TreeListModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); TreeList *childItem = static_cast<TreeList*>(index.internalPointer()); if (childItem == rootItem) return QModelIndex(); TreeList *parentItem = childItem->parent(); if (parentItem == rootItem) return QModelIndex(); return createIndex(parentItem->row(), 0, parentItem); }
void ForestTechniqueManager::createTreeList(osg::Node* terrain,const osg::Vec3& origin, const osg::Vec3& size,unsigned int numTreesToCreate,TreeList& trees) { float max_TreeHeight = sqrtf(size.length2()/(float)numTreesToCreate); float max_TreeWidth = max_TreeHeight*0.5f; float min_TreeHeight = max_TreeHeight*0.3f; float min_TreeWidth = min_TreeHeight*0.5f; trees.reserve(trees.size()+numTreesToCreate); for(unsigned int i=0;i<numTreesToCreate;++i) { Tree* tree = new Tree; tree->_position.set(random(origin.x(),origin.x()+size.x()),random(origin.y(),origin.y()+size.y()),origin.z()); tree->_color.set(random(128,255),random(128,255),random(128,255),255); tree->_width = random(min_TreeWidth,max_TreeWidth); tree->_height = random(min_TreeHeight,max_TreeHeight); tree->_type = 0; if (terrain) { osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(tree->_position,tree->_position+osg::Vec3(0.0f,0.0f,size.z())); osgUtil::IntersectionVisitor iv(intersector.get()); terrain->accept(iv); if (intersector->containsIntersections()) { osgUtil::LineSegmentIntersector::Intersections& intersections = intersector->getIntersections(); for(osgUtil::LineSegmentIntersector::Intersections::iterator itr = intersections.begin(); itr != intersections.end(); ++itr) { const osgUtil::LineSegmentIntersector::Intersection& intersection = *itr; tree->_position = intersection.getWorldIntersectPoint(); } } } trees.push_back(tree); } }
void ForestTechniqueManager::Cell::bin() { // put trees in appropriate cells. TreeList treesNotAssigned; for(TreeList::iterator titr=_trees.begin(); titr!=_trees.end(); ++titr) { Tree* tree = titr->get(); bool assigned = false; for(CellList::iterator citr=_cells.begin(); citr!=_cells.end() && !assigned; ++citr) { if ((*citr)->contains(tree->_position)) { (*citr)->addTree(tree); assigned = true; } } if (!assigned) treesNotAssigned.push_back(tree); } // put the unassigned trees back into the original local tree list. _trees.swap(treesNotAssigned); // prune empty cells. CellList cellsNotEmpty; for(CellList::iterator citr=_cells.begin(); citr!=_cells.end(); ++citr) { if (!((*citr)->_trees.empty())) { cellsNotEmpty.push_back(*citr); } } _cells.swap(cellsNotEmpty); }
void testToTree() { // build test data int i = 0; MapArrayFloat64 a("SomeName"); for (i = 0; i < TestPoints::N; i++) { a.Add(TestPoints::data[i]); } // verify tree TreeList* t = TreeValueCast<TreeList>(a.ToTree()); CPPUNIT_ASSERT(t != NULL); CPPUNIT_ASSERT_EQUAL(string("SomeName"), t->ElementName()); CPPUNIT_ASSERT_EQUAL(size_t(TestPoints::N), t->NumElements()); for (i = 0; i < TestPoints::N; i++) { const TreeFloat64* v = TreeValueCast<TreeFloat64>( t->ElementArray()[i] ); CPPUNIT_ASSERT(v != NULL); CPPUNIT_ASSERT_DOUBLES_EQUAL(TestPoints::data[i], v->Value(), TestPoints::resolution); } }
void xl_enter_prefix(Context *context, text name, native_fn fn, Tree *rtype, TreeList ¶meters, text symbol, text doc) // ---------------------------------------------------------------------------- // Enter a prefix into the context (called from .tbl files) // ---------------------------------------------------------------------------- { if (parameters.size()) { Tree *parmtree = xl_parameters_tree(parameters); Prefix *from = new Prefix(new Name(symbol), parmtree); Name *to = new Name(symbol); Rewrite *rw = context->Define(from, to); rw->native = fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterRewrite(from, to); rw2->type = rtype; to->code = fn; to->SetSymbols(s); xl_enter_builtin(MAIN, name, to, rw2->parameters, fn); xl_set_documentation(from, doc); } else { Name *n = new Name(symbol); n->SetInfo<PrefixDefinitionsInfo>(new PrefixDefinitionsInfo()); Rewrite *rw = context->Define(n, n); rw->native = fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterName(symbol, n, Rewrite::GLOBAL); rw2->type = rtype; n->code = fn; n->SetSymbols(s); TreeList noparms; xl_enter_builtin(MAIN, name, n, noparms, fn); xl_set_documentation(n, doc); } }
void xl_enter_form(Context *context, text name, native_fn fn, Tree *rtype, text form, TreeList ¶meters, text doc) // ---------------------------------------------------------------------------- // Enter an arbitrary form in the symbol table // ---------------------------------------------------------------------------- { Tree *from = xl_parse_text(form); Name *to = new Name(name); Rewrite *rw = context->Define(from, to); rw->native = fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterRewrite(from, to); rw2->type = rtype; to->code = fn; to->SetSymbols(s); xl_enter_builtin(MAIN, name, to, rw2->parameters, fn); ulong sz = parameters.size(); if (sz != rw2->parameters.size()) { std::cerr << "WARNING: Internal error on parameter count for " << name << "\n" << " " << form << "\n"; ulong sz2 = rw2->parameters.size(); for (ulong i = 0; i < sz || i < sz2; i++) { std::cerr << " #" << i << ": "; if (i < sz) std::cerr << "spec(" << parameters[i] << ") "; if (i < sz2) std::cerr << "form(" << rw2->parameters[i] << ") "; std::cerr << "\n"; } } xl_set_documentation(from, doc); }
void addTrees(const TreeList& trees) { _trees.insert(_trees.end(),trees.begin(),trees.end()); }
TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) { TreeList* retTL = this; FreeChunk* list = head(); assert(!list || list != list->next(), "Chunk on list twice"); assert(tc != NULL, "Chunk being removed is NULL"); assert(parent() == NULL || this == parent()->left() || this == parent()->right(), "list is inconsistent"); assert(tc->isFree(), "Header is not marked correctly"); assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); FreeChunk* prevFC = tc->prev(); TreeChunk* nextTC = TreeChunk::as_TreeChunk(tc->next()); assert(list != NULL, "should have at least the target chunk"); // Is this the first item on the list? if (tc == list) { // The "getChunk..." functions for a TreeList will not return the // first chunk in the list unless it is the last chunk in the list // because the first chunk is also acting as the tree node. // When coalescing happens, however, the first chunk in the a tree // list can be the start of a free range. Free ranges are removed // from the free lists so that they are not available to be // allocated when the sweeper yields (giving up the free list lock) // to allow mutator activity. If this chunk is the first in the // list and is not the last in the list, do the work to copy the // TreeList from the first chunk to the next chunk and update all // the TreeList pointers in the chunks in the list. if (nextTC == NULL) { assert(prevFC == NULL, "Not last chunk in the list") set_tail(NULL); set_head(NULL); } else { debug_only( if (PrintGC && Verbose) { gclog_or_tty->print_cr("Removing first but not only chunk in TreeList"); gclog_or_tty->print_cr("Node: " INTPTR_FORMAT " parent: " INTPTR_FORMAT " right: " INTPTR_FORMAT " left: " INTPTR_FORMAT, tc, tc->list()->parent(), tc->list()->right(), tc->list()->left()); gclog_or_tty->print_cr("Next before: " INTPTR_FORMAT " parent: " INTPTR_FORMAT " right: " INTPTR_FORMAT " left: " INTPTR_FORMAT, nextTC, nextTC->list()->parent(), nextTC->list()->right(), nextTC->list()->left()); gclog_or_tty->print_cr(" head: " INTPTR_FORMAT " tail: " INTPTR_FORMAT, nextTC->list()->head(), nextTC->list()->tail()); } ) // copy embedded list. nextTC->set_embedded_list(tc->embedded_list()); retTL = nextTC->embedded_list(); // Fix the pointer to the list in each chunk in the list. // This can be slow for a long list. Consider having // an option that does not allow the first chunk on the // list to be coalesced. for (TreeChunk* curTC = nextTC; curTC != NULL; curTC = TreeChunk::as_TreeChunk(curTC->next())) { curTC->set_list(retTL); } // Fix the parent to point to the new TreeList. if (retTL->parent() != NULL) { if (this == retTL->parent()->left()) { retTL->parent()->setLeft(retTL); } else { assert(this == retTL->parent()->right(), "Parent is incorrect"); retTL->parent()->setRight(retTL); } } // Fix the children's parent pointers to point to the // new list. assert(right() == retTL->right(), "Should have been copied"); if (retTL->right() != NULL) { retTL->right()->setParent(retTL); } assert(left() == retTL->left(), "Should have been copied"); if (retTL->left() != NULL) { retTL->left()->setParent(retTL); } retTL->link_head(nextTC); debug_only( if (PrintGC && Verbose) { gclog_or_tty->print_cr("Next after: " INTPTR_FORMAT " parent: " INTPTR_FORMAT " right: " INTPTR_FORMAT " left: " INTPTR_FORMAT, nextTC, nextTC->list()->parent(), nextTC->list()->right(), nextTC->list()->left()); gclog_or_tty->print_cr(" head: " INTPTR_FORMAT " tail: " INTPTR_FORMAT, nextTC->list()->head(), nextTC->list()->tail()); } ) assert(nextTC->isFree(), "Should be a free chunk"); }
TreeList* TreeList::as_TreeList(TreeChunk* tc) { // This first free chunk in the list will be the tree list. assert(tc->size() >= sizeof(TreeChunk), "Chunk is too small for a TreeChunk"); TreeList* tl = tc->embedded_list(); tc->set_list(tl); #ifdef ASSERT tl->set_protecting_lock(NULL); #endif tl->set_hint(0); tl->set_size(tc->size()); tl->link_head(tc); tl->link_tail(tc); tl->set_count(1); tl->init_statistics(); tl->setParent(NULL); tl->setLeft(NULL); tl->setRight(NULL); return tl; }
RearrangeNodesCommand::RearrangeNodesCommand(const std::list<boost::shared_ptr<NodeGui> >& nodes, QUndoCommand *parent) : QUndoCommand(parent) , _nodes() { ///1) Separate the nodes in trees they belong to, once a node has been "used" by a tree, mark it ///and don't try to reposition it for another tree ///2) For all trees : recursively position each nodes so that each input of a node is positionned as following: /// a) The first non mask input is positionned above the node /// b) All others non mask inputs are positionned on the left of the node, each one separated by the space of half a node /// c) All masks are positionned on the right of the node, each one separated by the space of half a node ///3) Move all trees so that they are next to each other and their "top level" node ///(the input that is at the highest position in the Y coordinate) is at the same ///Y level (node centers have the same Y) std::list<NodeGui*> usedNodes; ///A list of Tree ///Each tree is a lit of nodes with a boolean indicating if it was already positionned( "used" ) by another tree, if set to ///true we don't do anything /// Each node that doesn't have any output is a potential tree. TreeList trees; for (std::list<boost::shared_ptr<NodeGui> >::const_iterator it = nodes.begin(); it!=nodes.end(); ++it) { const std::list<boost::shared_ptr<Natron::Node> >& outputs = (*it)->getNode()->getOutputs(); if (outputs.empty()) { boost::shared_ptr<Tree> newTree(new Tree); newTree->buildTree(*it, usedNodes); trees.push_back(newTree); } } ///For all trees find out which one has the top most level node QPointF topLevelPos(0,INT_MAX); for (TreeList::iterator it = trees.begin(); it!=trees.end(); ++it) { const QPointF& treeTop = (*it)->getTopLevelNodeCenter(); if (treeTop.y() < topLevelPos.y()) { topLevelPos = treeTop; } } ///now offset all trees to be top aligned at the same level for (TreeList::iterator it = trees.begin(); it!=trees.end(); ++it) { const QPointF& treeTop = (*it)->getTopLevelNodeCenter(); QPointF delta(0,topLevelPos.y() - treeTop.y()); if (delta.x() != 0 || delta.y() != 0) { (*it)->moveAllTree(delta); } ///and insert the final result into the _nodes list const std::list<TreeNode>& treeNodes = (*it)->getNodes(); for (std::list<TreeNode>::const_iterator it2 = treeNodes.begin(); it2!=treeNodes.end(); ++it2) { NodeToRearrange n; n.node = it2->first; QSize size = n.node->getSize(); n.newPos = it2->second - QPointF(size.width() / 2.,size.height() / 2.); n.oldPos = n.node->pos(); _nodes.push_back(n); } } }