Esempio n. 1
0
    /**
     * Determine the axis-aligned bounding box containing the vertices of all
     * line segments at or beneath @a node in the block tree.
     *
     * @return  Determined AABox (might be empty (i.e., min > max) if no segments).
     */
    static AABoxd segmentBounds(LineSegmentBlockTreeNode const &node)
    {
        bool initialized = false;
        AABoxd bounds;

        // Iterative pre-order traversal.
        LineSegmentBlockTreeNode const *cur  = &node;
        LineSegmentBlockTreeNode const *prev = nullptr;
        while(cur)
        {
            while(cur)
            {
                LineSegmentBlock const &block = *cur->userData();

                if(block.totalCount())
                {
                    AABoxd boundsAtNode = segmentBounds(block.all());
                    if(initialized)
                    {
                        V2d_AddToBox(bounds.arvec2, boundsAtNode.min);
                    }
                    else
                    {
                        V2d_InitBox(bounds.arvec2, boundsAtNode.min);
                        initialized = true;
                    }
                    V2d_AddToBox(bounds.arvec2, boundsAtNode.max);
                }

                if(prev == cur->parentPtr())
                {
                    // Descending - right first, then left.
                    prev = cur;
                    if(cur->hasRight()) cur = cur->rightPtr();
                    else                cur = cur->leftPtr();
                }
                else if(prev == cur->rightPtr())
                {
                    // Last moved up the right branch - descend the left.
                    prev = cur;
                    cur = cur->leftPtr();
                }
                else if(prev == cur->leftPtr())
                {
                    // Last moved up the left branch - continue upward.
                    prev = cur;
                    cur = cur->parentPtr();
                }
            }

            if(prev)
            {
                // No left child - back up.
                cur = prev->parentPtr();
            }
        }

        return bounds;
    }
Esempio n. 2
0
    /**
     * Takes the line segment list and determines if it is convex, possibly
     * converting it into a BSP leaf. Otherwise, the list is divided into two
     * halves and recursion will continue on the new sub list.
     *
     * This is done by scanning all of the line segments and finding the one
     * that does the least splitting and has the least difference in numbers
     * of line segments on either side (why is this valued? -ds).
     *
     * If the line segments on the left side are convex create another leaf
     * else put the line segments into the left list.
     *
     * If the line segments on the right side are convex create another leaf
     * else put the line segments into the right list.
     *
     * @param node  Tree node for the block containing the line segments to
     *              be partitioned.
     *
     * @return  Newly created BSP subtree; otherwise @c nullptr (degenerate).
     */
    BspTree *partitionSpace(LineSegmentBlockTreeNode &node)
    {
        LOG_AS("Partitioner::partitionSpace");

        BspElement *bspElement = nullptr; ///< Built BSP map element at this node.
        BspTree *rightBspTree  = nullptr;
        BspTree *leftBspTree   = nullptr;

        // Pick a line segment to use as the next partition plane.
        if(LineSegmentSide *partSeg = choosePartition(node))
        {
            // Reconfigure the half-plane for the next round of partitioning.
            hplane.configure(*partSeg);

            /*
            LOG_TRACE("%s, segment side %p %i (segment #%i) %s %s")
                    << hplane.partition().asText()
                    << partSeg
                    << partSeg->lineSideId()
                    << lineSegments.indexOf(&partSeg->line())
                    << partSeg->from().origin().asText()
                    << partSeg->to().origin().asText();
            */

            // Take a copy of the current partition - we'll need this for any
            // BspNode we produce later.
            Partition partition(hplane.partition());

            // Create left and right block trees.
            /// @todo There should be no need to use additional independent
            ///       structures to contain these subsets.
            LineSegmentBlockTree rightTree(node.userData()->bounds());
            LineSegmentBlockTree leftTree(node.userData()->bounds());

            // Partition the line segements into two subsets according to their
            // spacial relationship with the half-plane (splitting any which
            // intersect).
            divideSegments(node, rightTree, leftTree);
            node.clear();

            addPartitionLineSegments(rightTree, leftTree);

            // Take a copy of the geometry bounds for each child/sub space
            // - we'll need this for any BspNode we produce later.
            AABoxd rightBounds = segmentBounds(rightTree);
            AABoxd leftBounds  = segmentBounds(leftTree);

            // Recurse on each suspace, first the right space then left.
            rightBspTree = partitionSpace(rightTree);
            leftBspTree  = partitionSpace(leftTree);

            // Collapse degenerates upward.
            if(!rightBspTree || !leftBspTree)
                return rightBspTree? rightBspTree : leftBspTree;

            // Make a new BSP node.
            bspElement = new BspNode(partition, rightBounds, leftBounds);
        }
        else
        {
            // No partition required/possible -- already convex (or degenerate).
            LineSegmentSides segments = collectAllSegments(node);
            node.clear();

            subspaces.append(ConvexSubspaceProxy());
            ConvexSubspaceProxy &convexSet = subspaces.last();

            convexSet.addSegments(segments);

            for(LineSegmentSide *seg : segments)
            {
                // Attribute the segment to the convex subspace.
                seg->setConvexSubspace(&convexSet);

                // Disassociate the segment from the block tree.
                seg->setBlockTreeNode(nullptr);
            }

            // Make a new BSP leaf.
            /// @todo Defer until necessary.
            BspLeaf *leaf = new BspLeaf;

            // Attribute the leaf to the convex subspace.
            convexSet.setBspLeaf(leaf);

            bspElement = leaf;
        }

        // Make a new BSP subtree and link up the children.
        BspTree *subtree = new BspTree(bspElement, nullptr/*no parent*/, rightBspTree, leftBspTree);
        if(rightBspTree) rightBspTree->setParent(subtree);
        if(leftBspTree)  leftBspTree->setParent(subtree);

        return subtree;
    }
int main(int argc, char** argv)
{
	try {
		// init command line parser
		util::ProgramOptions::init(argc, argv);

		int stack_id = optionStackId.as<int>();
		std::string comp_dir = optionComponentDir.as<std::string>();
		std::string pg_host = optionPGHost.as<std::string>();
		std::string pg_user = optionPGUser.as<std::string>();
		std::string pg_pass = optionPGPassword.as<std::string>();
		std::string pg_dbase = optionPGDatabase.as<std::string>();


		std::cout << "Testing PostgreSQL stores with stack ID " << stack_id << std::endl;

		// init logger
		logger::LogManager::init();
		logger::LogManager::setGlobalLogLevel(logger::Debug);

		// create new project configuration
		ProjectConfiguration pc;
		pc.setBackendType(ProjectConfiguration::PostgreSql);
		StackDescription stack;
		stack.id = stack_id;
		pc.setCatmaidStack(Raw, stack);
		pc.setComponentDirectory(comp_dir);
		pc.setPostgreSqlHost(pg_host);
		pc.setPostgreSqlUser(pg_user);
		pc.setPostgreSqlPassword(pg_pass);
		pc.setPostgreSqlDatabase(pg_dbase);

		PostgreSqlSliceStore sliceStore(pc, Membrane);

		// Add first set of slices
		boost::shared_ptr<Slice> slice1 = createSlice(10, 0);
		boost::shared_ptr<Slice> slice2 = createSlice(10, 1);
		boost::shared_ptr<Slice> slice3 = createSlice(10, 2);

		Slices slices = Slices();
		slices.add(slice1);
		slices.add(slice2);
		slices.add(slice3);

		Block block(0, 0, 0);
		sliceStore.associateSlicesToBlock(slices, block);

		Blocks blocks;
		blocks.add(block);
		Blocks missingBlocks;

		boost::shared_ptr<Slices> retrievedSlices =
				sliceStore.getSlicesByBlocks(blocks, missingBlocks);

		// Create conflict set where each slice
		ConflictSet conflictSet1;
		conflictSet1.addSlice(slice1->hashValue());
		conflictSet1.addSlice(slice2->hashValue());
		conflictSet1.addSlice(slice3->hashValue());

		ConflictSets conflictSets;
		conflictSets.add(conflictSet1);

		sliceStore.associateConflictSetsToBlock(conflictSets, block);
		boost::shared_ptr<ConflictSets> retrievedConflictSets =
				sliceStore.getConflictSetsByBlocks(blocks, missingBlocks);
		for (const ConflictSet& cs : *retrievedConflictSets) {
			std::cout << "ConflictSet hash: " << hash_value(cs);

			for (const SliceHash& sh : cs.getSlices()) {
				std::cout << " Slice hash: " << sh;
			}

			std::cout << std::endl;
		}

		PostgreSqlSegmentStore segmentStore(pc, Membrane);
		util::box<unsigned int, 2> segmentBounds(0, 0, 0, 0);
		std::vector<double> segmentFeatures;
		segmentFeatures.push_back(0.0);
		segmentFeatures.push_back(1.0);
		segmentFeatures.push_back(2.0);
		SegmentDescription segment(0, segmentBounds);
		segment.addLeftSlice(slice1->hashValue());
		segment.addRightSlice(slice2->hashValue());
		segment.setFeatures(segmentFeatures);

		boost::shared_ptr<SegmentDescriptions> segments = boost::make_shared<SegmentDescriptions>();
		segments->add(segment);

		segmentStore.associateSegmentsToBlock(*segments, block);

		boost::shared_ptr<SegmentDescriptions> retrievedSegments =
				segmentStore.getSegmentsByBlocks(blocks, missingBlocks, false);

	} catch (boost::exception& e) {

		handleException(e, std::cerr);
	}
}