Exemplo n.º 1
0
void FBXScene::ProcessNode(FbxNode* pNode, FbxNodeAttribute::EType attributeType)
{
	if( !pNode )
		return;

	FbxNodeAttribute* pNodeAttribute = pNode->GetNodeAttribute();

	if (pNodeAttribute)
	{
		if( pNodeAttribute->GetAttributeType() == attributeType )
		{
			switch(pNodeAttribute->GetAttributeType())
			{
			case FbxNodeAttribute::eSkeleton:
				{
					ProcessSkeleton(pNode);
					break;
				}

			case FbxNodeAttribute::eMesh:
				{
					ProcessMesh(pNode);
					break;
				}

			case FbxNodeAttribute::eNurbsCurve:
				{
					ProcessCurve(pNode);
					break;
				}

			default:
				break;
			};
		}
	}

	for( int i = 0; i < pNode->GetChildCount(); ++i )
	{
		ProcessNode(pNode->GetChild(i), attributeType);
	}
}
Exemplo n.º 2
0
// ------------------------------------------------------------------------------------------------
void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout, ConversionData& conv)
{
	ProcessCurve(def.Curve,meshout,conv);
}
Exemplo n.º 3
0
// ------------------------------------------------------------------------------------------------
void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result, 
													   const TempMesh& first_operand, 
													   ConversionData& conv)
{
	ai_assert(hs != NULL);

	const IfcPlane* const plane = hs->BaseSurface->ToPtr<IfcPlane>();
	if(!plane) {
		IFCImporter::LogError("expected IfcPlane as base surface for the IfcHalfSpaceSolid");
		return;
	}

	// extract plane base position vector and normal vector
	IfcVector3 p,n(0.f,0.f,1.f);
	if (plane->Position->Axis) {
		ConvertDirection(n,plane->Position->Axis.Get());
	}
	ConvertCartesianPoint(p,plane->Position->Location);

	if(!IsTrue(hs->AgreementFlag)) {
		n *= -1.f;
	}

	n.Normalize();

	// obtain the polygonal bounding volume
	boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh());
	if(!ProcessCurve(hs->PolygonalBoundary, *profile.get(), conv)) {
		IFCImporter::LogError("expected valid polyline for boundary of boolean halfspace");
		return;
	}

	IfcMatrix4 proj_inv;
	ConvertAxisPlacement(proj_inv,hs->Position);

	// and map everything into a plane coordinate space so all intersection
	// tests can be done in 2D space.
	IfcMatrix4 proj = proj_inv;
	proj.Inverse();

	// clip the current contents of `meshout` against the plane we obtained from the second operand
	const std::vector<IfcVector3>& in = first_operand.verts;
	std::vector<IfcVector3>& outvert = result.verts;

	std::vector<unsigned int>::const_iterator begin = first_operand.vertcnt.begin(), 
		end = first_operand.vertcnt.end(), iit;

	outvert.reserve(in.size());
	result.vertcnt.reserve(first_operand.vertcnt.size());

	std::vector<size_t> intersected_boundary_segments;
	std::vector<IfcVector3> intersected_boundary_points;

	// TODO: the following algorithm doesn't handle all cases. 
	unsigned int vidx = 0;
	for(iit = begin; iit != end; vidx += *iit++) {
		if (!*iit) {
			continue;
		}

		unsigned int newcount = 0;
		bool was_outside_boundary = !PointInPoly(proj * in[vidx], profile->verts);

		// used any more?
		//size_t last_intersected_boundary_segment;
		IfcVector3 last_intersected_boundary_point;

		bool extra_point_flag = false;
		IfcVector3 extra_point;

		IfcVector3 enter_volume;
		bool entered_volume_flag = false;

		for(unsigned int i = 0; i < *iit; ++i) {
			// current segment: [i,i+1 mod size] or [*extra_point,i] if extra_point_flag is set
			const IfcVector3& e0 = extra_point_flag ? extra_point : in[vidx+i];
			const IfcVector3& e1 = extra_point_flag ? in[vidx+i] : in[vidx+(i+1)%*iit];

			// does the current segment intersect the polygonal boundary?
			const IfcVector3& e0_plane = proj * e0;
			const IfcVector3& e1_plane = proj * e1;

			intersected_boundary_segments.clear();
			intersected_boundary_points.clear();

			const bool is_outside_boundary = !PointInPoly(e1_plane, profile->verts);
			const bool is_boundary_intersection = is_outside_boundary != was_outside_boundary;
			
			IntersectsBoundaryProfile(e0_plane, e1_plane, profile->verts, 
				intersected_boundary_segments, 
				intersected_boundary_points);
		
			ai_assert(!is_boundary_intersection || !intersected_boundary_segments.empty());

			// does the current segment intersect the plane?
			// (no extra check if this is an extra point)
			IfcVector3 isectpos;
			const Intersect isect =  extra_point_flag ? Intersect_No : IntersectSegmentPlane(p,n,e0,e1,isectpos);

#ifdef _DEBUG
			if (isect == Intersect_Yes) {
				const IfcFloat f = fabs((isectpos - p)*n);
				ai_assert(f < 1e-5);
			}
#endif

			const bool is_white_side = (e0-p)*n >= -1e-6;

			// e0 on good side of plane? (i.e. we should keep all geometry on this side)
			if (is_white_side) {
				// but is there an intersection in e0-e1 and is e1 in the clipping
				// boundary? In this case, generate a line that only goes to the
				// intersection point.
				if (isect == Intersect_Yes  && !is_outside_boundary) {
					outvert.push_back(e0);
					++newcount;

					outvert.push_back(isectpos);
					++newcount;
					
					/*
					// this is, however, only a line that goes to the plane, but not
					// necessarily to the point where the bounding volume on the
					// black side of the plane is hit. So basically, we need another 
					// check for [isectpos-e1], which should yield an intersection
					// point.
					extra_point_flag = true;
					extra_point = isectpos;

					was_outside_boundary = true; 
					continue; */

					// [isectpos, enter_volume] potentially needs extra points.
					// For this, we determine the intersection point with the
					// bounding volume and project it onto the plane. 
					/*
					const IfcVector3& enter_volume_proj = proj * enter_volume;
					const IfcVector3& enter_isectpos = proj * isectpos;

					intersected_boundary_segments.clear();
					intersected_boundary_points.clear();

					IntersectsBoundaryProfile(enter_volume_proj, enter_isectpos, profile->verts, 
						intersected_boundary_segments, 
						intersected_boundary_points);

					if(!intersected_boundary_segments.empty()) {

						vec = vec + ((p - vec) * n) * n;
					}
					*/				

					//entered_volume_flag = true;
				}
				else {
					outvert.push_back(e0);
					++newcount;
				}
			}
			// e0 on bad side of plane, e1 on good (i.e. we should remove geometry on this side,
			// but only if it is within the bounding volume).
			else if (isect == Intersect_Yes) {
				// is e0 within the clipping volume? Insert the intersection point
				// of [e0,e1] and the plane instead of e0.
				if(was_outside_boundary) {
					outvert.push_back(e0);
				}
				else {
					if(entered_volume_flag) {
						const IfcVector3& fix_point = enter_volume + ((p - enter_volume) * n) * n;
						outvert.push_back(fix_point);
						++newcount;
					}

					outvert.push_back(isectpos);	
				}
				entered_volume_flag = false;
				++newcount;
			}
			else { // no intersection with plane or parallel; e0,e1 are on the bad side
			
				// did we just pass the boundary line to the poly bounding?
				if (is_boundary_intersection) {

					// and are now outside the clipping boundary?
					if (is_outside_boundary) {
						// in this case, get the point where the clipping boundary
						// was entered first. Then, get the point where the clipping
						// boundary volume was left! These two points with the plane
						// normal form another plane that intersects the clipping
						// volume. There are two ways to get from the first to the
						// second point along the intersection curve, try to pick the
						// one that lies within the current polygon.

						// TODO this approach doesn't handle all cases

						// ...

						IfcFloat d = 1e20;
						IfcVector3 vclosest;
						BOOST_FOREACH(const IfcVector3& v, intersected_boundary_points) {
							const IfcFloat dn = (v-e1_plane).SquareLength();
							if (dn < d) {
								d = dn;
								vclosest = v;
							}
						}

						vclosest = proj_inv * vclosest;
						if(entered_volume_flag) {
							const IfcVector3& fix_point = vclosest + ((p - vclosest) * n) * n;
							outvert.push_back(fix_point);
							++newcount;

							entered_volume_flag = false;
						}

						outvert.push_back(vclosest);
						++newcount;

						//outvert.push_back(e1);
						//++newcount;
					}
					else {
						entered_volume_flag = true;

						// we just entered the clipping boundary. Record the point
						// and the segment where we entered and also generate this point.
						//last_intersected_boundary_segment = intersected_boundary_segments.front();
						//last_intersected_boundary_point = intersected_boundary_points.front();

						outvert.push_back(e0);
						++newcount;

						IfcFloat d = 1e20;
						IfcVector3 vclosest;
						BOOST_FOREACH(const IfcVector3& v, intersected_boundary_points) {
							const IfcFloat dn = (v-e0_plane).SquareLength();
							if (dn < d) {
								d = dn;
								vclosest = v;
							}
						}

						enter_volume = proj_inv * vclosest;
						outvert.push_back(enter_volume);
						++newcount;
					}
				}				
				// if not, we just keep the vertex
				else if (is_outside_boundary) {
					outvert.push_back(e0);
					++newcount;

					entered_volume_flag = false;
				}
			}

			was_outside_boundary = is_outside_boundary;
			extra_point_flag = false;
		}
Exemplo n.º 4
0
// ------------------------------------------------------------------------------------------------
void ProcessClosedProfile(const IfcArbitraryClosedProfileDef& def, TempMesh& meshout, ConversionData& conv)
{
	ProcessCurve(def.OuterCurve,meshout,conv);
}
void MPointCreator::ProcessPoints(
                         const MHTRouteCandidate::PointData& rData1,
                         const MHTRouteCandidate::RouteSegment& rSegment1,
                         const MHTRouteCandidate::PointData& rData2,
                         std::vector<const SimpleLine*>& vecCurvesBetweenPoints)
{
    Point Pt1(false);
    if (rData1.GetPointProjection() != NULL)
        Pt1 = *(rData1.GetPointProjection());
    else
        Pt1 = rData1.GetPointGPS();

    Point Pt2(false);
    if (rData2.GetPointProjection() != NULL)
        Pt2 = *(rData2.GetPointProjection());
    else
        Pt2 = rData2.GetPointGPS();

    if (AlmostEqual(Pt1, Pt2))
    {
        Interval<Instant> TimeInterval(rData1.GetTime(),
                                       rData2.GetTime(),
                                       true,
                                       rData1.GetTime() == rData2.GetTime());

        AttributePtr<UPoint> pUPoint(new UPoint(TimeInterval, Pt1, Pt1));
        m_pResMPoint->Add(*pUPoint);

        assert(vecCurvesBetweenPoints.size() == 0);
    }
    else
    {
        const shared_ptr<IMMNetworkSection>& pSection1 = rData1.GetSection();
        const shared_ptr<IMMNetworkSection>& pSection2 = rData2.GetSection();

        if (pSection1 == NULL || !pSection1->IsDefined() ||
            pSection2 == NULL || !pSection2->IsDefined())
        {
            // at least one point is offroad

            Interval<Instant> TimeInterval(
                                          rData1.GetTime(),
                                          rData2.GetTime(),
                                          true,
                                          rData1.GetTime() == rData2.GetTime());

            AttributePtr<UPoint> pUPoint(new UPoint(TimeInterval, Pt1, Pt2));
            m_pResMPoint->Add(*pUPoint);
        }
        else if (pSection1 == pSection2) // Same section
        {
            const SimpleLine* pSectionCurve = pSection1->GetCurve();

            AttributePtr<SimpleLine> pSubline(new SimpleLine(0));
            MMUtil::SubLine(pSectionCurve,
                            Pt1,
                            Pt2,
                            pSection1->GetCurveStartsSmaller(),
                            m_dNetworkScale,
                            *pSubline);

            if (pSubline->IsDefined() &&
                pSubline->StartPoint().IsDefined() &&
                pSubline->EndPoint().IsDefined())
            {
                Interval<Instant> TimeInterval(
                                          rData1.GetTime(),
                                          rData2.GetTime(),
                                          true,
                                          rData1.GetTime() == rData2.GetTime());

                //assert(AlmostEqual(Pt1, pSubline->StartPoint()));

                ProcessCurve(*pSubline, TimeInterval);
            }
        }
        else // different sections
        {
            // Calculate total length of curves

            const SimpleLine* pSection1Curve = pSection1->GetCurve();

            AttributePtr<SimpleLine> pSubline1(new SimpleLine(0));
            MMUtil::SubLine(pSection1Curve,
                            Pt1,
                            !rSegment1.HasUTurn() ? pSection1->GetEndPoint() :
                                                    pSection1->GetStartPoint(),
                            pSection1->GetCurveStartsSmaller(),
                            m_dNetworkScale,
                            *pSubline1);

            double dLenCurve1 = MMUtil::CalcLengthCurve(pSubline1.get(),
                                                        m_dNetworkScale);


            const SimpleLine* pSection2Curve = pSection2->GetCurve();

            AttributePtr<SimpleLine> pSubline2(new SimpleLine(0));
            MMUtil::SubLine(pSection2Curve,
                            pSection2->GetStartPoint(),
                            Pt2,
                            pSection2->GetCurveStartsSmaller(),
                            m_dNetworkScale,
                            *pSubline2);

            double dLenCurve2 = MMUtil::CalcLengthCurve(pSubline2.get(),
                                                        m_dNetworkScale);


            double dLength = dLenCurve1 + dLenCurve2;


            const size_t nCurves = vecCurvesBetweenPoints.size();
            for (size_t i = 0; i < nCurves; ++i)
            {
                dLength += MMUtil::CalcLengthCurve(vecCurvesBetweenPoints[i],
                                                   m_dNetworkScale);
            }

            // Total time
            DateTime Duration = rData2.GetTime() - rData1.GetTime();
            Duration.Abs();

            // Process first curve

            DateTime TimeEnd(rData1.GetTime());

            if (!pSubline1 ||
                AlmostEqual(dLenCurve1, 0.0))
            {
                Interval<Instant> TimeInterval(rData1.GetTime(),
                                               TimeEnd,
                                               true, true);
                AttributePtr<UPoint> pUPoint(new UPoint(TimeInterval,
                                                        Pt1, Pt1));
                m_pResMPoint->Add(*pUPoint);
            }
            else
            {
                TimeEnd = rData1.GetTime() +
                           DateTime(datetime::durationtype,
                                    (uint64_t)(((Duration.millisecondsToNull()
                                                / dLength) * dLenCurve1) + .5));
                Interval<Instant> TimeInterval(rData1.GetTime(),
                                               TimeEnd,
                                               true,
                                               rData1.GetTime() == TimeEnd);
                ProcessCurve(*pSubline1, TimeInterval, dLenCurve1);
            }

            // Process curves in between

            for (size_t i = 0; i < nCurves; ++i)
            {
                const SimpleLine* pCurve = vecCurvesBetweenPoints[i];
                if (pCurve == NULL)
                    continue;

                double dLenCurve = MMUtil::CalcLengthCurve(pCurve,
                                                           m_dNetworkScale);
                if (AlmostEqual(dLenCurve, 0.0))
                    continue;

                DateTime TimeStart = TimeEnd;
                TimeEnd = TimeStart +
                          DateTime(datetime::durationtype,
                                    (uint64_t)(((Duration.millisecondsToNull()
                                                / dLength) * dLenCurve) + .5));

                Interval<Instant> TimeInterval(TimeStart,
                                               TimeEnd,
                                               true, false);

                ProcessCurve(*pCurve, TimeInterval, dLenCurve);
            }

            // Process last curve

            if (!pSubline2 ||
                AlmostEqual(dLenCurve2, 0.0))
            {
                DateTime TimeStart = TimeEnd;
                TimeEnd = rData2.GetTime();
                Interval<Instant> TimeInterval(TimeStart,
                                               TimeEnd,
                                               true, true);
                AttributePtr<UPoint> pUPoint(new UPoint(TimeInterval,
                                                        Pt2, Pt2));
                m_pResMPoint->Add(*pUPoint);
            }
            else
            {
                assert(TimeEnd.millisecondsToNull() <=
                       rData2.GetTime().millisecondsToNull());
                DateTime TimeStart = TimeEnd;
                TimeEnd = rData2.GetTime();
                Interval<Instant> TimeInterval(TimeStart,
                                               TimeEnd,
                                               true, false);
                ProcessCurve(*pSubline2, TimeInterval, dLenCurve2);
            }
        }
    }
}