VTK随笔十:VTK图形处理(封闭性检测、联通区域分析、多分辨率处理)

news2024/11/16 6:49:55

一、封闭性检测

        如果一条边只被一个多边形包含,那么这条边就是边界边。
是否存在边界边是检测一个网格模型是否封闭的重要特征。
        vtkFeatureEdges是一个非常重要的类,该类能够提取多边形网格模型中四种类型的边。
1)边界边。即只被一个多边形或者一条边包含的边。
2)非流形边。被3个或者3个以上的多边形包含的边即为非流形边。
3)特征边。上节中也提到,需要设置一个特征角的阈值,当包含同一条边的两个三角形的法向量的夹角大于该阈值时,即为一个特征边。
4)流形边。只被两个多边形包含的边即为流形边。

        可以使用该类来检测是否存在边界边,并依此来判断网格是否封闭。检测出网格是否封闭之后可以通过类vtkFillHoleFilter将漏洞填补起来。

示例代码:

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkSphereSource.h>
#include <vtkSelectionNode.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkInformation.h>
#include <vtkExtractSelection.h>
#include <vtkPolyDataMapper.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkFeatureEdges.h>
#include <vtkFillHolesFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkCamera.h>
#include <QDebug>

void GenerateData(vtkSmartPointer<vtkPolyData> input)
{
    vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->Update();

    vtkSmartPointer<vtkIdTypeArray> ids = vtkSmartPointer<vtkIdTypeArray>::New();
    ids->SetNumberOfComponents(1);
    ids->InsertNextValue(2);
    ids->InsertNextValue(10);

    vtkSmartPointer<vtkSelectionNode> selectionNode = vtkSmartPointer<vtkSelectionNode>::New();
    selectionNode->SetFieldType(vtkSelectionNode::CELL);
    selectionNode->SetContentType(vtkSelectionNode::INDICES);
    selectionNode->SetSelectionList(ids);
    selectionNode->GetProperties()->Set(vtkSelectionNode::INVERSE(), 1);

    vtkSmartPointer<vtkSelection> selection = vtkSmartPointer<vtkSelection>::New();
    selection->AddNode(selectionNode);

    vtkSmartPointer<vtkExtractSelection> extractSelection = vtkSmartPointer<vtkExtractSelection>::New();
    extractSelection->SetInputData(0, sphereSource->GetOutput());
    extractSelection->SetInputData(1, selection);
    extractSelection->Update();

    vtkSmartPointer<vtkDataSetSurfaceFilter> surfaceFilter = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
    surfaceFilter->SetInputConnection(extractSelection->GetOutputPort());
    surfaceFilter->Update();

    input->ShallowCopy(surfaceFilter->GetOutput());
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    vtkSmartPointer<vtkPolyData> input = vtkSmartPointer<vtkPolyData>::New();
    GenerateData(input);

    vtkSmartPointer<vtkFeatureEdges> featureEdges = vtkSmartPointer<vtkFeatureEdges>::New();
    featureEdges->SetInputData(input);
    featureEdges->BoundaryEdgesOn();
    featureEdges->FeatureEdgesOff();
    featureEdges->ManifoldEdgesOff();
    featureEdges->NonManifoldEdgesOff();
    featureEdges->Update();

    int numberOfOpenEdges = featureEdges->GetOutput()->GetNumberOfCells();
    if(numberOfOpenEdges)
    {
        qDebug()<<"该网格模型不是封闭的...";
    }
    else
    {
        qDebug()<<"该网格模型是封闭的...";
        return 0;
    }

    vtkSmartPointer<vtkFillHolesFilter> fillHolesFilter = vtkSmartPointer<vtkFillHolesFilter>::New();
    fillHolesFilter->SetInputData(input);
    fillHolesFilter->Update();

    vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();
    normals->SetInputConnection(fillHolesFilter->GetOutputPort());
    normals->ConsistencyOn();
    normals->SplittingOff();
    normals->Update();

    double leftViewport[4] = {0.0, 0.0, 0.5, 1.0};
    double rightViewport[4] = {0.5, 0.0, 1.0, 1.0};

    vtkSmartPointer<vtkPolyDataMapper> originalMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    originalMapper->SetInputData(input);

    vtkSmartPointer<vtkProperty> backfaceProp = vtkSmartPointer<vtkProperty>::New();
    backfaceProp->SetDiffuseColor(0.89,0.81,0.34);

    vtkSmartPointer<vtkActor> originalActor = vtkSmartPointer<vtkActor>::New();
    originalActor->SetMapper(originalMapper);
    originalActor->SetBackfaceProperty(backfaceProp);
    originalActor->GetProperty()->SetDiffuseColor(1.0, 0.3882, 0.2784);

    vtkSmartPointer<vtkPolyDataMapper> edgeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    edgeMapper->SetInputData(featureEdges->GetOutput());
    vtkSmartPointer<vtkActor> edgeActor =
        vtkSmartPointer<vtkActor>::New();
    edgeActor->SetMapper(edgeMapper);
    edgeActor->GetProperty()->SetEdgeColor(0.,0.,1.0);
    edgeActor->GetProperty()->SetEdgeVisibility(1);
    edgeActor->GetProperty()->SetLineWidth(5);

    vtkSmartPointer<vtkPolyDataMapper> filledMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    filledMapper->SetInputData(normals->GetOutput());

    vtkSmartPointer<vtkActor> filledActor = vtkSmartPointer<vtkActor>::New();
    filledActor->SetMapper(filledMapper);
    filledActor->GetProperty()->SetDiffuseColor(1.0, 0.3882, 0.2784);

    vtkSmartPointer<vtkRenderer> leftRenderer = vtkSmartPointer<vtkRenderer>::New();
    leftRenderer->SetViewport(leftViewport);
    leftRenderer->AddActor(originalActor);
    leftRenderer->AddActor(edgeActor);
    leftRenderer->SetBackground(1.0, 1.0, 1.0);

    vtkSmartPointer<vtkRenderer> rightRenderer = vtkSmartPointer<vtkRenderer>::New();
    rightRenderer->SetViewport(rightViewport);
    rightRenderer->AddActor(filledActor);
    rightRenderer->SetBackground(1.0, 1.0, 1.0);

    vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
    renderWindow->AddRenderer(leftRenderer);
    renderWindow->AddRenderer(rightRenderer);

    QVTKOpenGLNativeWidget w;
    w.resize(640, 320);
    w.setRenderWindow(renderWindow);
    w.setWindowTitle("PolyDataClosed");
    w.show();

    leftRenderer->GetActiveCamera()->SetPosition(0, -1, 0);
    leftRenderer->GetActiveCamera()->SetFocalPoint(0, 0, 0);
    leftRenderer->GetActiveCamera()->SetViewUp(0, 0, 1);
    leftRenderer->GetActiveCamera()->Azimuth(30);
    leftRenderer->GetActiveCamera()->Elevation(30);
    leftRenderer->ResetCamera();
    rightRenderer->SetActiveCamera(leftRenderer->GetActiveCamera());

    return a.exec();
}

 运行效果:

二、联通区域分析 

        许多图形数据中,并非只包含一个对象(连通区域)。而在处理这些图形数据时,有时需要对每一个对象单独处理或者让其单独显示。比如利用MarchingCube 方法提取三维图像中的等值面,得到的结果往往是存在多个连通的对象区域,这时就需要对图形数据做连通区域分析,提取每个连通区域并计算其属性信息,以此来得到需要的连通区域。

 示例代码:

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkSphereSource.h>
#include <vtkConeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkAppendPolyData.h>
#include <vtkPolyDataConnectivityFilter.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->SetRadius(10);
    sphereSource->SetThetaResolution(10);
    sphereSource->SetPhiResolution(10);
    sphereSource->Update();

    vtkSmartPointer<vtkConeSource> coneSource = vtkSmartPointer<vtkConeSource>::New();
    coneSource->SetRadius(5);
    coneSource->SetHeight(10);
    coneSource->SetCenter(25,0,0);
    coneSource->Update();

    vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
    appendFilter->AddInputData(sphereSource->GetOutput());
    appendFilter->AddInputData(coneSource->GetOutput());
    appendFilter->Update();

    vtkSmartPointer<vtkPolyDataConnectivityFilter> connectivityFilter = vtkSmartPointer<vtkPolyDataConnectivityFilter>::New();
    connectivityFilter->SetInputData(appendFilter->GetOutput());
    connectivityFilter->SetExtractionModeToCellSeededRegions();
    connectivityFilter->AddSeed(100);
    connectivityFilter->Update();

    vtkSmartPointer<vtkPolyDataMapper> originalMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    originalMapper->SetInputConnection(appendFilter->GetOutputPort());
    originalMapper->Update();

    vtkSmartPointer<vtkActor> originalActor = vtkSmartPointer<vtkActor>::New();
    originalActor->SetMapper(originalMapper);

    vtkSmartPointer<vtkPolyDataMapper> extractedMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    extractedMapper->SetInputConnection(connectivityFilter->GetOutputPort());
    extractedMapper->Update();

    vtkSmartPointer<vtkActor> extractedActor = vtkSmartPointer<vtkActor>::New();
    extractedActor->SetMapper(extractedMapper);

    double leftViewport[4] = {0.0, 0.0, 0.5, 1.0};
    double rightViewport[4] = {0.5, 0.0, 1.0, 1.0};

    vtkSmartPointer<vtkRenderer> leftRenderer = vtkSmartPointer<vtkRenderer>::New();
    leftRenderer->SetViewport(leftViewport);
    leftRenderer->AddActor(originalActor);
    leftRenderer->SetBackground(0.8, 0.8, 0.8);

    vtkSmartPointer<vtkRenderer> rightRenderer = vtkSmartPointer<vtkRenderer>::New();
    rightRenderer->SetViewport(rightViewport);
    rightRenderer->AddActor(extractedActor);
    rightRenderer->SetBackground(1.0, 1.0, 1.0);

    vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
    renderWindow->AddRenderer(leftRenderer);
    renderWindow->AddRenderer(rightRenderer);

    QVTKOpenGLNativeWidget w;
    w.resize(640, 320);
    w.setRenderWindow(renderWindow);
    w.setWindowTitle("PolyDataConnectedCompExtract");
    w.show();

    return a.exec();
}

运行效果:

vtkPolyDataConnectivityFilter类用于实现连通区域分析,它有以下典型函数:

1、SetExtractionModeToLargestRegion():用于提取具有最多点的连通区域。

2、SetExtractionModeToAllRegion():用于连通区域标记,配合函数ColorRegionsOn()一起使用。

3、SetExtractionModeToSpecifiedRegion():用于提取一个或多个连通区域,需要通过AddSpecifiedRegion()来添加需要提取的边界号。

4、SetExtractionModeToClosestPointRegion():该模式下需要使用 SetClosestPoint()函数设置一个空间点坐标,其执行结果为离该点最近的连通区域。

5、SetExtractionModeToPointSeededRegions():该模式下需要使用 AddSeed()函数添加种子点,提取种子点所在的区域。

6、SetExtractionModeToCellSeededRegions():该模式下需要使用 AddSeed()函数添加种子单元,提取种子单元所在的区域。

三、多分辨率处理 

        模型抽取(Decimation)和细化(Subdivision)是两个相反的操作,是三角形网格模型多分辨率处理中的两个重要操作。使用这两个操作可以在保持模型拓扑结构的同时,得到不同分辨率的网格模型。模型抽取的作用是减少模型数据中的点数据和单元数据,便于模型的后续处理与交互渲染,这类似于图像数据的降采样。而网格细化则是利用一定的细化规则,在给定的初始网格中插入新的点,从而不断细化出新的网格单元,在极限细化情况下,该网格能够收敛于一个光滑曲面。

1、网格抽取

        VTK 中主要有三种网格抽取类:vtkDecimatePro、vtkQuadricDecimation 和 vtkQuadricClustering。vtkDecimatePro 是最常用的,是用一种边塌陷的方法来删除点和单元,处理速度比较快,而且可以方便地控制网格抽取的幅度,得到不同级别的模型数据。 

示例代码:

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkPolyDataReader.h>
#include <vtkDecimatePro.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkCamera.h>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    vtkSmartPointer<vtkPolyDataReader> reader = vtkSmartPointer<vtkPolyDataReader>::New();
    reader->SetFileName("D:/data/fran_cut.vtk");
    reader->Update();
    vtkSmartPointer<vtkPolyData> original  =  reader->GetOutput();

    qDebug() << "抽取前:------------" ;
    qDebug() << "模型点数为: " << original->GetNumberOfPoints();
    qDebug() << "模型面数为: " << original->GetNumberOfPolys();

    vtkSmartPointer<vtkDecimatePro> decimate = vtkSmartPointer<vtkDecimatePro>::New();
    decimate->SetInputData(original);
    decimate->SetTargetReduction(.80);
    decimate->Update();

    vtkSmartPointer<vtkPolyData> decimated = decimate->GetOutput();
    qDebug() << "抽取后:" << "------------";
    qDebug() << "模型点数为:" << decimated->GetNumberOfPoints();
    qDebug() << "模型面数为:" << decimated->GetNumberOfPolys();

    vtkSmartPointer<vtkPolyDataMapper> origianlMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    origianlMapper->SetInputData(original);

    vtkSmartPointer<vtkActor> origianlActor = vtkSmartPointer<vtkActor>::New();
    origianlActor->SetMapper(origianlMapper);

    vtkSmartPointer<vtkPolyDataMapper> decimatedMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    decimatedMapper->SetInputData(decimated);

    vtkSmartPointer<vtkActor> decimatedActor = vtkSmartPointer<vtkActor>::New();
    decimatedActor->SetMapper(decimatedMapper);

    double leftViewport[4] = {0.0, 0.0, 0.5, 1.0};
    double rightViewport[4] = {0.5, 0.0, 1.0, 1.0};

    vtkSmartPointer<vtkRenderer> leftRenderer = vtkSmartPointer<vtkRenderer>::New();
    leftRenderer->SetViewport(leftViewport);
    leftRenderer->AddActor(origianlActor);
    leftRenderer->SetBackground(1.0, 1.0, 1.0);

    vtkSmartPointer<vtkRenderer> rightRenderer = vtkSmartPointer<vtkRenderer>::New();
    rightRenderer->SetViewport(rightViewport);
    rightRenderer->AddActor(decimatedActor);
    rightRenderer->SetBackground(1.0, 1.0, 1.0);

    leftRenderer->GetActiveCamera()->SetPosition(0, -1, 0);
    leftRenderer->GetActiveCamera()->SetFocalPoint(0, 0, 0);
    leftRenderer->GetActiveCamera()->SetViewUp(0, 0, 1);
    leftRenderer->GetActiveCamera()->Azimuth(30);
    leftRenderer->GetActiveCamera()->Elevation(30);
    leftRenderer->ResetCamera();
    rightRenderer->SetActiveCamera(leftRenderer->GetActiveCamera());

    vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
    renderWindow->AddRenderer(leftRenderer);
    renderWindow->AddRenderer(rightRenderer);

    QVTKOpenGLNativeWidget w;
    w.resize(640, 320);
    w.setRenderWindow(renderWindow);
    w.setWindowTitle("PolyDataDecimation");
    w.show();

    return a.exec();
}

运行效果:

 

        vtkOuadricDecimation也可以实现三角网格的简化,并能较好地逼近原模型。该类虽然提供了 SetTargetReduction()函数用于设置模型简化程度,但是最终简化率并非严格等于程序中设置的简化率。可以通过GetActualReduction()函数来获取最终模型简化率。

        vtkQuadricClustering 是三种模型抽取类中最快的一种,能够处理大数据模型。通过 StartAppend()、Append()和 EndAppend()函数可以将整个模型分为多个网格片处理,从而避免一次性处理整个模型,减少内存开支,提高处理效率。

        三个网格抽取类都接受的是vtkPolyData的三角网格数据:如果vkPolyData 数据为多边形网格数据,需要先通过 vtkTriangleFilter 将多边形网络数据转换为三角网格数据。 

2、网格细化 

        VTK中实现网格细化的类有 vtkLinearSubdivisionFilter、vtkLoopSubdivisionFilter 和vtkButerflySubdivisionFilter。 

 

        vtkInterpolatingSubdivisionFilter 内部提供了 SetNumberOfSubdivisions()函数来设置细化的次数,其中每次细化后模型的三角面片的个数将是细化前的4倍。因此,在对网格模型进行n次细分后,该模型的面片个数将成为原始模型面片数目的4n倍。vtkLinearSubdivisionFilter 实现了一种线性细分算法,每次细分将每个三角片面生成4个新的面片,该算法比较简单,速度快,但是细分后不能产生光滑的模型。vtkLoopSubdivisionFilter 实现了Loop 细分算法,每次细分会将一个三角面片生成4个三角面片。该方法能够生成光滑的连续曲面,应用比较广泛。vtkButterflySubdivisionFilter实现了蝶形细分算法。 

示例代码:

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataAlgorithm.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkLinearSubdivisionFilter.h>
#include <vtkLoopSubdivisionFilter.h>
#include <vtkButterflySubdivisionFilter.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    vtkSmartPointer<vtkPolyData> originalMesh;

    vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->Update();
    originalMesh = sphereSource->GetOutput();

    double numberOfViewports = 3;
    int numberOfSubdivisions = 2;

    vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();

    for(unsigned i = 0; i < numberOfViewports; i++)
    {
        vtkSmartPointer<vtkPolyDataAlgorithm> subdivisionFilter;
        switch(i)
        {
        case 0:
            subdivisionFilter = vtkSmartPointer<vtkLinearSubdivisionFilter>::New();
            dynamic_cast<vtkLinearSubdivisionFilter *> (subdivisionFilter.GetPointer())->SetNumberOfSubdivisions(numberOfSubdivisions);
            break;
        case 1:
            subdivisionFilter =  vtkSmartPointer<vtkLoopSubdivisionFilter>::New();
            dynamic_cast<vtkLoopSubdivisionFilter *> (subdivisionFilter.GetPointer())->SetNumberOfSubdivisions(numberOfSubdivisions);
            break;
        case 2:
            subdivisionFilter = vtkSmartPointer<vtkButterflySubdivisionFilter>::New();
            dynamic_cast<vtkButterflySubdivisionFilter *> (subdivisionFilter.GetPointer())->SetNumberOfSubdivisions(numberOfSubdivisions);
            break;
        default:
            break;
        }

        subdivisionFilter->SetInputData(originalMesh);
        subdivisionFilter->Update();

        vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();

        renderWindow->AddRenderer(renderer);
        renderer->SetViewport(static_cast<double>(i)/numberOfViewports,0,static_cast<double>(i+1)/numberOfViewports,1);
        renderer->SetBackground(1.0, 1.0, 1.0);

        vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
        mapper->SetInputConnection(subdivisionFilter->GetOutputPort());
        vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
        actor->SetMapper(mapper);
        renderer->AddActor(actor);
        renderer->ResetCamera();
    }

    QVTKOpenGLNativeWidget w;
    w.resize(640, 320);
    w.setRenderWindow(renderWindow);
    w.setWindowTitle("PolyDataSubdivision");
    w.show();

    return a.exec();
}

 运行效果:

        模型细化算子仅对三角网格数据有效,因此在处理多边形数据时,需要通过vtkTriangleFilter将多边形数据转换为三角网格数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2087485.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解释预测的艺术

如何以人性化的方式解释你的模型 可直接在橱窗里购买&#xff0c;或者到文末领取优惠后购买&#xff1a; 数据科学家职责的一个重要部分是解释模型预测。通常&#xff0c;接受解释的人不是技术人员。如果你开始谈论成本函数、超参数或 p 值&#xff0c;你将会遇到茫然的表情。我…

List集合和Set集合

Collection&#xff1a; Collection 不唯一&#xff0c;无序 List 不唯一&#xff0c;有序 Set 唯一&#xff0c;无序 ArrayList&#xff1a;内部使用长度可变的数组&#xff0c;遍历查询效率高 LinkedList&#xff1a;采用双向链表实现&#xff0c;增删改效率比较高 ArrayL…

【小白深度学习入门】【2】池化层详解:工作原理、维度计算、池化类型

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

Dataworks_PySpark开发流程

PySpark是由Spark官方开发的Python语言第三方库&#xff0c;Python开发者可以通过使用python语言来编写Spark程序和SparkSQL完成开发。 之所以采用PySpark而不采用Java/Scala&#xff0c;是由于&#xff1a; Dataworks可通过将代码在线写入DataWorks Python资源的方式&#xf…

Android 12系统源码_输入系统(一)认识Android的输入系统

前言 问渠那得清如许&#xff0c;为有源头活水来。对于大多数现代操作系统中&#xff0c;“事件”就是它们的“活水源头”&#xff0c;正是在“事件和消息”的不断产生、流转和处理中&#xff0c;整个软件系统才能“动”起来。 Android系统有一套从底层Linux内核到上层应用程…

合宙LuatOS产品规格书——Air780EQ

合宙Air780EQ&#xff0c; 基于移芯EC716E高端平台&#xff0c; 集成LTE 3GPP Release 13技术&#xff0c;确保高速、稳定的网络连接&#xff1b; 广泛兼容各大运营商网络&#xff0c;实现真正的全网通设计&#xff0c;提升产品市场适应性与灵活性。 Air780EQ 4G全网通模块核…

Unity(2022.3.41LTS) - 角色控制器和3D刚体

目录 一. 角色控制 二. 3D刚体 一. 角色控制 名称&#xff1a;功能&#xff1a;坡度限制将碰撞器限制为仅爬升比指示值更陡峭&#xff08;以度为单位&#xff09;的斜坡。步长偏移只有当楼梯离地面比指示值更近时&#xff0c;角色才会爬上楼梯。此值不应大于 Character Contr…

追求全能还是专精?——AI模型的未来趋势探讨

AI模型&#xff1a;追求全能还是专精&#xff1f; 近日&#xff0c;OpenAI预计在秋季推出代号为“草莓”的新AI。从专注于数学问题到处理主观营销策略&#xff0c;"草莓"模型展现出惊人的多样性。而这种全能型 AI 是否代表了未来趋势&#xff1f;相比专攻于某一领域的…

【离线查询 滑动窗口】2747. 统计没有收到请求的服务器数目

本文涉及知识点 离线查询 C算法&#xff1a;滑动窗口总结 LeetCode2747. 统计没有收到请求的服务器数目 给你一个整数 n &#xff0c;表示服务器的总数目&#xff0c;再给你一个下标从 0 开始的 二维 整数数组 logs &#xff0c;其中 logs[i] [server_id, time] 表示 id 为…

【Kafka】Windows下安装Kafka(全面)

目录 1.前提条件 2.下载 3.安装 4.环境变量配置 5.验证 1.前提条件 1.先安装zookeeper&#xff1a; 【Zookeeper】Windows下安装Zookeeper&#xff08;全面&#xff09;-CSDN博客https://blog.csdn.net/weixin_57259781/article/details/141679454 2.还需要安装scala: …

设计模式 -- 外观模式(Facade Pattern)

1 问题引出 组建一个家庭影院 DVD 播放器、投影仪、自动屏幕、环绕立体声、爆米花机,要求完成使用家庭影院的功能&#xff0c;其过程为&#xff1a; 直接用遥控器&#xff1a;统筹各设备开关 开爆米花机&#xff0c;放下屏幕 &#xff0c;开投影仪 &#xff0c;开音响&#xf…

坐牢第三十二天(c++)

一.作业 仿照string类&#xff0c;实现myString #include <iostream> #include <cstring> // 引入cstring以使用memcpy using namespace std; class myString {char *str; // 记录c风格的字符串int size; // 记录字符串的实际长度 public:// 无参构造myString():…

循环流网络的费用问题

循环流网络的费用问题 费用为负的网络流循环流网络的费用一些题目[UVa1659 Help Little Laura](https://onlinejudge.org/index.php?optioncom_onlinejudge&Itemid8&category24&pageshow_problem&problem4534)[Aizu-2230 How to Create a Good Game](https://…

[LLM][Prompt Engineering]:思维链(CoT)

思维链 思维链1. 思维链提示方法和增强策略1.1 简单的思维链提示1.2 示例形式的思维链提示1.3 思维链提示的后处理方案1.4 拓展推理结构 2. CoT的能力来源&#xff1a;为什么思维链提示能显著提升大语言模型在推理任务上的效果&#xff1f; 强大的逻辑推理是大语言模型“智能涌…

深度学习——LLM大模型分词

1. 前言 自从chatgpt出现&#xff0c;大模型的发展就进入了快车道&#xff0c;各种各样的大模型卷上天&#xff0c;作为一个在大模型时代的科研人&#xff0c;即使你不向前&#xff0c;也会被时代裹挟着向前&#xff0c;所以还是自己走快一点比较好&#xff0c;免得被后浪拍死…

呆错图床系统,一款开源免费的图床系统

源码介绍 呆错图床系统是一款免费的PHP图床程序&#xff0c;核心功能是提供图片外链服务、图床API服务、图片CDN加速与破解防盗链。 下载地址&#xff1a; https://download.csdn.net/download/huayula/89693127

基于七牛云上传,下载文件

准备工作 1.创建一个七牛云账号 2.登录账号&#xff0c;进入个人中心&#xff0c;创建一组密钥&#xff08;ak和sk&#xff09; 3. 创建一个公有的存储空间&#xff08;桶&#xff09; 注&#xff1a;存储地区的选择基于你的用户的分布主要在哪里。 七牛云直接白送10GB给我们…

给鼠标一个好看的指针特效 鼠标光标如何修改形状?

许多爱美的小伙伴们都想着如何给自己的电脑打扮一下&#xff0c;用各种各样的途径来美化我们的电脑。今天我们给大家分享一下&#xff0c;如何美化鼠标效果&#xff0c;给鼠标指针修改成一个非常好看的形状~ 一起来看几组鼠标的效果&#xff0c;小编我给大家做了个录屏&#x…

LuaJit分析(十一)去除string.dump函数

Lua脚本中的string.dump函数用于生成字节码文件&#xff0c;根据对 luajit -b命令的分析可以得出&#xff0c;最终dump出字节码文件都是使用的string.dump函数。 因此即使我们的指令顺序被打乱&#xff0c;通过loadfile系统调用&#xff0c;再通过string.dump调用&#xff0c;…

缓存解决方案。Redis 和 Amazon ElastiCache 比较

欢迎来到雲闪世界。Redis 和 Amazon ElastiCache 等缓存解决方案是通过将频繁访问的数据存储在内存中来提高应用程序性能的热门选择。让我们从实施简单性、性能、成本和维护方面对它们进行比较。 实施简单 设置 Redis 需要在基础设施或云实例上安装和配置 Redis 服务器。它可…